【发布时间】:2014-08-13 10:12:33
【问题描述】:
我已经编写了我对 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;
哪个编译器是正确的,为什么?
【问题讨论】:
-
顺便说一句,如果这是重复的,我不会感到惊讶,所以如果是,请关闭。不过搜索起来并不容易。
-
当你说:with gcc, with clang, etc.时请务必指定版本。
-
@MarcGlisse:我不明白它为什么重要,但它是 Clang 3.6.0 和 GCC 4.8.1。
-
@Mehrdad:考虑到是否在 SFINAE 上下文中考虑可见性在 C++11 中发生了变化,这很重要。早于那个(或遵循旧规则,包括 g++4.4)的编译器将由于可访问性问题而失败,而使用 C++11 规则的编译器不会考虑它。
-
@David:但我想我已经说过我在 C++03 模式下执行此操作......这还不够吗?
标签: c++ template-meta-programming sfinae c++03 access-specifier