我已经尝试了与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. g 4.8编译器遵守C 11规则并忽略SFINAE上下文中不可访问的成员,而clang编译器遵守C 03所在的成员(构造函数)找到并选择此案例),但访问检查使代码无效. VS(无论你使用的是什么版本)都不遵守C 11或C 03规则,它似乎完全忽略了sizeof中的访问说明符.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。