【发布时间】:2012-09-04 01:13:05
【问题描述】:
我稍作修改以适用于我的所有测试用例:
template< class T >
class is_default_constructible {
typedef int yes;
typedef char no;
// the second version does not work
#if 1
template<int x, int y> class is_equal {};
template<int x> class is_equal<x,x> { typedef void type; };
template< class U >
static yes sfinae( typename is_equal< sizeof U(), sizeof U() >::type * );
#else
template<int x> class is_okay { typedef void type; };
template< class U >
static yes sfinae( typename is_okay< sizeof U() >::type * );
#endif
template< class U >
static no sfinae( ... );
public:
enum { value = sizeof( sfinae<T>(0) ) == sizeof(yes) };
};
为什么它在两个模板参数版本上都能正常工作,而在普通版本(设置#if 0)上却不行?
这是编译器错误吗?我正在使用 Visual Studio 2010。
我使用了以下测试:
BOOST_STATIC_ASSERT( is_default_constructible<int>::value );
BOOST_STATIC_ASSERT( is_default_constructible<bool>::value );
BOOST_STATIC_ASSERT( is_default_constructible<std::string>::value );
BOOST_STATIC_ASSERT( !is_default_constructible<int[100]>::value );
BOOST_STATIC_ASSERT( is_default_constructible<const std::string>::value );
struct NotDefaultConstructible {
const int x;
NotDefaultConstructible( int a ) : x(a) {}
};
BOOST_STATIC_ASSERT( !is_default_constructible<NotDefaultConstructible>::value );
struct DefaultConstructible {
const int x;
DefaultConstructible() : x(0) {}
};
BOOST_STATIC_ASSERT( is_default_constructible<DefaultConstructible>::value );
我真的很茫然:
- 另一个版本的两个测试失败:
int[100]和NotDefaultConstructible。所有测试都使用两个模板参数版本成功。 - Visual Studio 2010 不支持
std::is_default_constructible。但是,我的问题是为什么这两种实现有任何差异,以及为什么一种有效而另一种无效。
【问题讨论】:
-
为什么不检查您是否已经在标准库中以
std::is_default_constructible的形式拥有它? -
什么不起作用?它在 g++ 上运行良好,除了
BOOST_STATIC_ASSERT( !is_default_constructible<int[100]>::value ); -
@BЈовић 如果断言失败,并且该断言是正确的,那么它肯定不能正常工作吗?
-
g++-4.7.1 可以正确编译这两个变体。
-
你应该使用
typedef char yes[1]; typedef char no[2];来保证它们是不同的尺寸(int和char理论上可以是相同的尺寸);另外我觉得它更容易阅读。
标签: c++ templates metaprogramming