有谁知道如何使用一个参数检测构造函数?例如,此结构应该具有否定结果:
struct MyStruct
{
MyStruct( int x, int x2 ) : y( x ) {}
int y;
};
我在这里有一个很好的SFINAE检查,看看一个类或结构是否是一个具有特定数量参数的构造函数。这是参数计数为3的那个:
template <typename T>
struct HasCtor3Args
{
struct Any { template <typename U> operator U( void ); };
template <typename U>
static int32 SFINAE( decltype( U( Any( ), Any( ), Any( ) ) ) * );
template <typename U>
static int8 SFINAE( ... );
static const bool value = sizeof( SFINAE<T>( NULL ) ) == sizeof( int32 );
};
这似乎工作正常,因为Any
结构可以转换为参数应该是的任何类型。但问题是在尝试仅使用一个参数检测构造函数时。由于将Any
默认为与T
相同的类型,SFINAE检查似乎总是返回true,从而检测到复制构造函数。
修改和更新: 我做过几次尝试,似乎没有一次尝试...这是我能得到的最接近的,但不起作用,因为它总是返回真实。我的想法是尝试解决复制构造函数而不是第一个“全部捕获”调用:
template <typename T>
struct HasCtor1Args
{
struct Any
{
template <typename U>
operator U( ) const;
};
template <typename U>
static int32 SFINAE( decltype( U( Any( ) ) ) * );
// Try to catch the copy ctor here
T MakeT( void );
template <typename U>
static int8 SFINAE( decltype( U( MakeT( ) ) ) * );
template <typename U>
static int8 SFINAE( ... );
static const bool value = sizeof( SFINAE<T>( NULL ) ) == sizeof( int32 );
};
我也尝试使用explicit关键字,以及C ++ 11的= delete功能,然后意识到我需要使用的编译器(微软)不允许这样做。我也尝试在转换类型U上使用std :: enable_if,尽管我遇到了函数模板参数无法默认的错误。
答案 0 :(得分:2)
虽然上午的批评仍然存在,但这里有一个版本来检测只有一个 1参数非复制,非移动ctor的类型。它使用SFINAE来限制Any
的转换。
注意:带有默认参数的其他ctors会导致歧义(例如my_type(int, double=0);
。这是一个非常有限的解决方案。
#include <cstdint>
#include <type_traits>
template <typename T>
struct HasCtor1Args
{
struct Any
{
template
<
typename U, typename SFINAE =
typename std::enable_if< false == std::is_same<U,T>::value, U >::type
>
operator U() const;
};
template <typename U>
static int32_t SFINAE( decltype( U( Any( ) ) ) * );
template <typename U>
static int8_t SFINAE( ... );
static const bool value = sizeof( SFINAE<T>( nullptr ) ) == sizeof( int32_t );
};
struct my_type
{
my_type(int);
my_type(my_type const&);
};
int main()
{
static_assert(HasCtor1Args<my_type> :: value, "epic fail");
}