C++ 为包含typedef的类型专门化模板

C++ 为包含typedef的类型专门化模板,c++,sfinae,typetraits,C++,Sfinae,Typetraits,我有一个模板类,需要专门用于包含特定typedef的模板参数。所以我需要两个定义,一个用于有typedef的情况,另一个用于没有typedef的情况 我的问题是我不知道如何否定SFINAE。我显然可以消除非特殊参数的特殊情况,但我不知道如何消除特殊参数的默认情况 所以我尝试了这样的部分专业化: struct NormalType { }; struct SpecialType { typedef int special; }; template <typename T, typenam

我有一个模板类,需要专门用于包含特定typedef的模板参数。所以我需要两个定义,一个用于有typedef的情况,另一个用于没有typedef的情况

我的问题是我不知道如何否定SFINAE。我显然可以消除非特殊参数的特殊情况,但我不知道如何消除特殊参数的默认情况

所以我尝试了这样的部分专业化:

struct NormalType { };

struct SpecialType { typedef int special; };

template <typename T, typename IsSpecial = void>
struct DetectSpecial {
    void detected() { std::cout << "Not special...\n"; }
};

template <typename T>
struct DetectSpecial<T, typename T::special> {
    void detected() { std::cout << "Special!\n"; }
};
struct NormalType{};
结构特殊类型{typedef int special;};
模板
结构检测特殊{
检测到void(){std::cout以下内容可能会有所帮助:(C++11)(C++03)

#包括
模板
这个班有特别的课程
{
私人:
模板结构虚拟;
模板
静态标准::uint8_t检查(虚拟*);
模板静态标准::uint16_t检查(…);
公众:
静止的
constexpr bool value=sizeof(检查(0))==sizeof(标准::uint8_t);
};
以下内容可能会有所帮助:(C++11)(C++03)

#包括
模板
这个班有特别的课程
{
私人:
模板结构虚拟;
模板
静态标准::uint8_t检查(虚拟*);
模板静态标准::uint16_t检查(…);
公众:
静止的
constexpr bool value=sizeof(检查(0))==sizeof(标准::uint8_t);
};

所需的最小更改是在依赖于
T::special
的专门化中插入一些表达式,并生成
void
(以匹配默认参数)。例如:

template<class T>
struct void_alias
{
    typedef void type;
};

template <typename T>
struct DetectSpecial<T, typename void_alias<typename T::special>::type> {
    void detected() { std::cout << "Special!\n"; }
};
模板
结构void\u别名
{
typedef-void型;
};
模板
结构检测特殊{

void detected(){std::cout所需的最小更改是在依赖于
T::special
的专门化中插入一些表达式,并生成
void
(以匹配默认参数)。例如:

template<class T>
struct void_alias
{
    typedef void type;
};

template <typename T>
struct DetectSpecial<T, typename void_alias<typename T::special>::type> {
    void detected() { std::cout << "Special!\n"; }
};
模板
结构void\u别名
{
typedef-void型;
};
模板
结构检测特殊{

void detected(){std::cout这将不起作用,因为
T::special
不是
void
。当您实例化
DetectSpecial
时,您正在实例化
DetectSpecial
,它与
DetectSpecial
不匹配(部分专门化)。这将不起作用,因为
T::special
不是
void
。当您实例化
DetectSpecial
时,您正在实例化
DetectSpecial
,它与
DetectSpecial
不匹配(部分专门化)。除非我得到警告,函数模板的默认模板参数是C++11扩展名,我也需要它在C++03编译器中工作。@JanHudec@dyp:显然,我今天有一个思维障碍,因为我没有意识到制作一个指针以获得总是可以构造的东西的简单技巧。@JanHudec如果
t::special
是一个引用(但您可以使用与
void\u别名
或其他别名相同的技巧)除非我得到警告,函数模板的默认模板参数是C++11扩展,我也需要它在C++03编译器中工作。@JanHudec@dyp:显然,我今天有一个思维障碍,因为我没有意识到制作一个指针以获得总是可以构造的东西的简单技巧。@JanHudec如果
t::special
是一个引用(但您可以使用与
void\u别名
或其他别名相同的技巧)