我有一个模板类,需要专门用于包含特定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"; }
};
但专业化未被使用(as SSCCE on ideone)。
我也考虑过使用enable_if
,但是我没有看到如何将它用于格式良好和非格式良好的表达式而不是真/假。
对于包含特定typedef的类型,以不同方式定义DetectSpecial
的最简单方法是什么(typedef的值可能是任何值;它的存在很重要)?
哦,我仍然坚持使用一些C ++ 03编译器。无论如何,我认为SFINAE没有任何变化。
答案 0 :(得分:3)
所需的最小更改是在依赖于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"; }
};
答案 1 :(得分:1)
以下可能会有所帮助:(C ++ 11)https://ideone.com/XISlZ6(C ++ 03)https://ideone.com/egKrcL
#include <cstdint>
template <typename U>
class has_special
{
private:
template<typename T> struct dummy;
template<typename T>
static std::uint8_t check(dummy<typename T::special>*);
template<typename T> static std::uint16_t check(...);
public:
static
constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t);
};