这个简单的代码可以用clang编译,但不能用g编译。里面有什么未定义的吗?(需要模板函数让clang高兴)GCC8.2.0(与-std=c 17一起使用)说运算符
#include <cstddef>
#include <utility>
#include <sstream>
template<class Out>
Out&& operator<<(Out&& out, std::nullptr_t) {
out << "nullptr";
return std::forward<Out>(out); }
struct A : std::stringstream { };
int main() {
A{} << nullptr;
}
我相信这是由GCC的Bug 51577引起的。
您的代码导致std::的实例化__is_insertable
template<typename _Ostream, typename _Tp, typename = void>
struct __is_insertable : false_type {};
template<typename _Ostream, typename _Tp>
struct __is_insertable<_Ostream, _Tp,
__void_t<decltype(declval<_Ostream&>()
<< declval<const _Tp&>())>>
: true_type {};
如果一切顺利,您的运算符
现在由于错误51577,您的运算符
注意GCC9编译这段代码。这是因为有一个新的重载
basic_ostream& operator<<( std::nullptr_t );
…在C 17中添加,因此无论您的运算符是否__is_insertable
都可以成功实例化
1这是因为[temp. dep.候选]/1:
对于postfix表达式是依赖名称的函数调用,使用通常的查找规则([base. lookup.unqual]、[base.lookup.argdep])查找候选函数,但以下情况除外:
>
对于使用非限定名称查找的查找部分,仅找到来自模板定义上下文的函数声明。
对于使用关联命名空间([base. lookup.argdep])的查找部分,只能找到在模板定义上下文或模板实例化上下文中找到的函数声明。
您的运算符