为什么编译器不接受基于 enable_if 的专业化
Why specialization based on enable_if is not picked up by compiler
我想针对 class 的某种类型专门化 class,例如基于 std::is_arithmetic。虽然编译器没有 "see" 我基于 "enable_if" 的专业化并选择 principle/main 模板。你能帮我解决这个问题吗...
下面是使用 g++ 4.8
编译后的代码片段和输出
#include < iostream >
#include < type_traits >
#include < string >
template < typename T1, typename T2 = void >
struct TestT
{
static const bool is_int = false;
static const bool is_str = false;
};
template < typename T>
struct TestT < T,
std::enable_if< std::is_arithmetic<t>::value, T >::type >
{
static const bool is_int = true;
static const bool is_str = false;
};
template < typename T>
struct TestT < std::string, T >
{
static const bool is_int = false;
static const bool is_str = true;
};
class enum TestE
{
Last
};
int main(int argc, char* argv[])
{
std::cout << "Enum is_int: " << TestT<TestE>::is_int
<< ", is_str: " << TestT<TestE>::is_str << std::endl;
std::cout << "string is_int: " << TestT<std::string>::is_int
<< ", is_str: " << TestT<std::string>::is_str << std::endl;
std::cout << "int is_int: " << TestT<int>::is_int
<< ", is_str: " << TestT<int>::is_str << std::endl;
return 0;
}
上面的输出是:
Enum is_int: 0, is_str: 0
// Expected
string is_int: 0, is_str: 1
// Expected
int is_int: 0, is_str: 0
// Not expected
非常感谢您的帮助,在此先感谢您
您需要保留第二个参数(由 ::type
别名的类型)未指定或 void
以便它与主模板的默认参数相匹配:
struct TestT<T,
std::enable_if<std::is_arithmetic<T>::value>::type>
您还需要在 std::enable_if
语句之前添加 typename
,或使用 std::enable_if_t
(并省略 ::type
):
struct TestT<T, std::enable_if_t<std::is_arithmetic<T>::value>>
第二专业也是如此:
template<>
struct TestT<std::string>
{
static const bool is_int = false;
static const bool is_str = true;
};
最后,在本专业中,is_int
应设置为 true
:
template<typename T>
struct TestT<T, std::enable_if_t<std::is_arithmetic<T>::value>>
{
static const bool is_int = true;
static const bool is_str = false;
};
更好的版本可能是保留单一专业化并使用 std::is_same
来测试 int
和类型特征来测试字符串:
template<class T>struct is_string:std::false_type{};
template<>struct is_string<std::string>:std::true_type{};
template<std::size_t N>struct is_string<char const(&)[N]>:std::true_type{};
template<>struct is_string<char const*>:std::true_type{};
template<>struct is_string<char const*const>:std::true_type{};
template<>struct is_string<char const*volatile>:std::true_type{};
// on and on...
template<typename T>
struct TestT
{
static const bool is_int = std::is_same<T, int>();
static const bool is_str = is_string<T>();
};
我想针对 class 的某种类型专门化 class,例如基于 std::is_arithmetic。虽然编译器没有 "see" 我基于 "enable_if" 的专业化并选择 principle/main 模板。你能帮我解决这个问题吗... 下面是使用 g++ 4.8
编译后的代码片段和输出#include < iostream >
#include < type_traits >
#include < string >
template < typename T1, typename T2 = void >
struct TestT
{
static const bool is_int = false;
static const bool is_str = false;
};
template < typename T>
struct TestT < T,
std::enable_if< std::is_arithmetic<t>::value, T >::type >
{
static const bool is_int = true;
static const bool is_str = false;
};
template < typename T>
struct TestT < std::string, T >
{
static const bool is_int = false;
static const bool is_str = true;
};
class enum TestE
{
Last
};
int main(int argc, char* argv[])
{
std::cout << "Enum is_int: " << TestT<TestE>::is_int
<< ", is_str: " << TestT<TestE>::is_str << std::endl;
std::cout << "string is_int: " << TestT<std::string>::is_int
<< ", is_str: " << TestT<std::string>::is_str << std::endl;
std::cout << "int is_int: " << TestT<int>::is_int
<< ", is_str: " << TestT<int>::is_str << std::endl;
return 0;
}
上面的输出是:
Enum is_int: 0, is_str: 0
// Expected
string is_int: 0, is_str: 1
// Expected
int is_int: 0, is_str: 0
// Not expected
非常感谢您的帮助,在此先感谢您
您需要保留第二个参数(由 ::type
别名的类型)未指定或 void
以便它与主模板的默认参数相匹配:
struct TestT<T,
std::enable_if<std::is_arithmetic<T>::value>::type>
您还需要在 std::enable_if
语句之前添加 typename
,或使用 std::enable_if_t
(并省略 ::type
):
struct TestT<T, std::enable_if_t<std::is_arithmetic<T>::value>>
第二专业也是如此:
template<>
struct TestT<std::string>
{
static const bool is_int = false;
static const bool is_str = true;
};
最后,在本专业中,is_int
应设置为 true
:
template<typename T>
struct TestT<T, std::enable_if_t<std::is_arithmetic<T>::value>>
{
static const bool is_int = true;
static const bool is_str = false;
};
更好的版本可能是保留单一专业化并使用 std::is_same
来测试 int
和类型特征来测试字符串:
template<class T>struct is_string:std::false_type{};
template<>struct is_string<std::string>:std::true_type{};
template<std::size_t N>struct is_string<char const(&)[N]>:std::true_type{};
template<>struct is_string<char const*>:std::true_type{};
template<>struct is_string<char const*const>:std::true_type{};
template<>struct is_string<char const*volatile>:std::true_type{};
// on and on...
template<typename T>
struct TestT
{
static const bool is_int = std::is_same<T, int>();
static const bool is_str = is_string<T>();
};