Clang vs. GCC vs. MSVC中的SFINAE和可见性检查——这是正确的
SFINAE and visibility-checking in Clang vs. GCC vs. MSVC -- which is correct?
我已经写了我对is_default_constructible
的c++ 03兼容实现的尝试:
template<class = void> struct is_default_constructible;
template<> struct is_default_constructible<>
{
protected:
// Put base typedefs here to avoid pollution
struct twoc { char a, b; };
template<bool> struct test { typedef char type; };
template<class T> static T declval();
};
template<> struct is_default_constructible<>::test<true> { typedef twoc type; };
template<class T> struct is_default_constructible : is_default_constructible<>
{
private:
template<class U> static typename test<!!sizeof(::new U())>::type sfinae(U*);
template<class U> static char sfinae(...);
public:
static bool const value = sizeof(sfinae<T>(0)) > 1;
};
当我在GCC (-std=c++03
)中测试它时,它返回0
,因为构造函数是不可见的:
class Test { Test(); };
int main()
{
return is_default_constructible<Test>::value;
}
当我在Visual c++中测试它时(不同的版本都有相同的行为),我得到了1
。
当我在Clang(也是-std=c++03
)中测试它时,我得到:
error: calling a private constructor of class 'Test'
template<class U> static typename test<!!sizeof(::new U())>::type sfinae(U *);
^
note: while substituting explicitly-specified template arguments into function template 'sfinae'
static bool const value = sizeof(sfinae<T>(0)) > 1;
^
note: in instantiation of template class 'is_default_constructible<Test>' requested here
return is_default_constructible<Test>::value;
^
error: calling a private constructor of class 'Test'
template<class U> static typename test<!!sizeof(::new U())>::type sfinae(U *);
^
note: while substituting deduced template arguments into function template 'sfinae' [with U = Test]
static bool const value = sizeof(sfinae<T>(0)) > 1;
^
note: in instantiation of template class 'is_default_constructible<Test>' requested here
return is_default_constructible<Test>::value;
哪个编译器是正确的,为什么?
该代码在c++ 03中无效,但在c++ 11中有效。c++ 4.8编译器遵循c++ 11规则并忽略SFINAE上下文中不可访问的成员,而clang编译器遵循c++ 03,其中成员(在本例中为构造函数)被找到并选择,但访问检查使代码无效。VS(无论你使用的是什么版本)不遵守c++ 11或c++ 03规则,它似乎完全忽略了sizeof
内部的访问说明符。
相关文章:
- valgrind-hellgrind与泄漏检查的结果不同
- C++模板来检查友元函数的存在
- 检查输入是否不是整数或数字
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 试图让变量检查数组中的某些内容
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 检查值是否在集合p1和p2中,但不在p3中
- C++概念:如何使用'concept'检查模板化结构的属性?
- 概念TS检查忽略私有访问修饰符
- 检查 std::shared_ptr<> 的当前底层类型是否为 T
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- VS Studio C++奇怪的输出(质数检查)
- 检查失败:1 == numelements()(1 vs. 1792)必须在Tensorflow C 中具有一个元素
- 从多个来源检查NULL:共享_ptr vs double指针
- 条件检查:if(x==0) vs. if(!x)
- 如何检查是否所有字段都已填写?[C++,VS 2015,Windows窗体]
- 为什么 int vs 布尔类型检查失败
- 线程安全惰性初始化:静态vs std::call_once vs双重检查锁定
- Clang vs. GCC vs. MSVC中的SFINAE和可见性检查——这是正确的
- File stat()vs access()来检查目录上的权限