c++ - 是什么阻止了 Boost.Format 表单使用我的可选 int 流运算符重载?

标签 c++ boost boost-format

我希望能够使用 std::optional<int>使用 Boost.Format。

#include <iostream>
#include <optional>
#include <boost/format.hpp>

struct SomeType
{
    int x;
};

std::ostream& operator<<(std::ostream& os, const SomeType& t)  
{
    os << t.x;
    return os;
}

std::ostream& operator<<(std::ostream& os, const std::optional<int>& t)  
{
    os << t.value_or(0);
    return os;
}

void test()
{
    SomeType t{42};
    std::cout << (boost::format("%s") % t); //this is fine
    std::optional<int> i = 42;
    std::cout << (boost::format("%s") % i); //nope
}

上面的代码给出了以下编译器错误:

opt/compiler-explorer/libs/boost_1_68_0/boost/format/feed_args.hpp:99:12: error: no match for 'operator<<' (operand types are 'std::basic_ostream<char>' and 'const std::optional<int>')
    os << x ;
    ~~~^~~~

如果我简单地传递 i 就没有编译器错误直接到std::cout .

最佳答案

boost::format("%s") % i调用 operator<< .编译期间遵循名称查找规则以查找 operator<< .

对于 boost::format("%s") % t , 都是结构 SomeTypestd::ostream& operator<<(std::ostream& os, const SomeType& t)在全局命名空间中定义,使用 ADL,operator<<找到了。

对于 (boost::format("%s") % i) , std::optional在命名空间 std 中定义, 但对应 operator<<在全局命名空间中定义。通过使用 ADL,boost 将无法找到它。和

non-ADL lookup examines function declarations with external linkage that are visible from the template definition context,

所以编译器无法找到 operator<<你定义的。

解决方法:将 std::optional 包装在您自己的 ReferenceWrapper 中,然后在定义 ReferenceWrapper 的同一命名空间中为您的包装器定义插入器。

关于c++ - 是什么阻止了 Boost.Format 表单使用我的可选 int 流运算符重载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53477226/

相关文章:

c++ - 是否有一些方法可以使 c++ 类中的一个函数在不同的线程中运行

c++ - C++ 没有重载时间函数所以我们不需要写 NULL 是有原因的吗?

c++ - 从不同的模块导入函数

c++ - 使用 Boost::Fiber 的多个共享工作池

c++ - 在 C++ 中使用赋值运算符重载将类对象的数据复制到另一个类对象时出错

c++ - 使用带有自定义图形的 r_c_shortest 路径( boost )

c++ - 为什么 Boost Format 和 printf 在相同的格式字符串上表现不同

c++ - 如何使用 boost::format 对变量中包含小数位数的数字进行零填充?

c++ - boost::format 和自定义打印标准容器

c++ - 查找已安装的正确 Boost 版本以及如何删除旧版本