以下代码snipplet尝试实现'std :: is_constructible< A,int>':
#include <type_traits>
struct A {
// A(int);
};
template< typename T >
struct cstr_int
{
static int mi;
template< typename C >
static typename std::enable_if<
std::is_same< decltype( T( mi ) ), T >::value, char >::type choose( C * );
static long choose( ... );
enum { value = ( sizeof( decltype( choose( & mi ) ) ) == 1 ) };
};
bool const b1 = cstr_int< A >::value;
使用g ++这很好用;使用clang ++打印以下错误:
tmp/sfinae04.cc:14:29: error: no matching conversion for functional-style cast from 'int' to 'A'
std::is_same< decltype( T( mi ) ), T >::value, char >::type choose( C * );
^~~~~
tmp/sfinae04.cc:20:17: note: in instantiation of template class 'cstr_int<A>' requested here
bool const b1 = cstr_int< A >::value;
^
tmp/sfinae04.cc:3:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const A' for 1st argument
struct A {
^
tmp/sfinae04.cc:3:8: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'A' for 1st argument
struct A {
^
tmp/sfinae04.cc:3:8: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided
1 error generated.
版本信息:clang版本3.3(主干172418)(llvm / trunk 172417),g ++(Debian 4.7.2-4)4.7.2。
我的问题: 恕我直言,这应该是一个SFINAE。我在这里想念一下,或者clang ++有问题吗?
(我知道有is_constructible()但我不允许使用它 - 这不是我的问题。)
答案 0 :(得分:6)
虽然它看起来像是替换失败,但它实际上是在模板实例化期间检测到的失败,因此是可诊断的错误。
不 SFINAE上下文,因为enable_if
不依赖于推断的模板参数。
这有效:
template< typename T >
struct cstr_int
{
static int mi;
template< typename C >
static typename std::enable_if<
std::is_same< decltype( C( mi ) ), C >::value, char >::type choose( C * );
static long choose( ... );
enum { value = ( sizeof( decltype( choose( (T*)0 ) ) ) == 1 ) };
};