是什么阻止 Boost.Format 表单使用我的可选 int 流运算符重载?
What's preventing Boost.Format form using my stream operator overload for optional int?
我希望能够将 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
,struct SomeType
和std::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 的同一命名空间中为您的包装器定义插入器。
我希望能够将 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
,struct SomeType
和std::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 的同一命名空间中为您的包装器定义插入器。