如何自定义模板以不包含某些类型



遵循模板类类型特定的函数,如何自定义模板代码以不针对某些类型进行编译?如果问题不清楚,请看这个例子。

///** template class ***/
template<typename T>
class testClass{
testClass();
T parameter;
}
template<typename T>
void testClass<T>::print(){cout<<parameter.value<<endl;}

上述类应该适用于以下类型:

 //** types file **/
    class paramtype1{
    int value;
    }
    class paramtype2{
    int value;
    }
    class paramtype3{
    }

如您所见,paramtype3没有value,所以我收到一个编译错误,说value未定义。我知道,如果我想为某种类型专门化模板类函数,我需要做:

template<>
void testClass<paramtype1>::print(){cout<<parameter.value<<endl;}

但是,有没有办法反过来,只排除某些特定类型?

如果要启用/禁用完整的类/结构,可以使用SFINAE和部分专用化。

下面是一个 C++17 示例

template <typename T, typename = void>
struct testClass;
template <typename T>
struct testClass<T, std::void_t<decltype(T::value)>>
 {
   testClass()
    { };
   T parameter;
   void print()
    { std::cout << parameter.value << std::endl; }
 };

如果您只想启用/禁用print()功能,则必须对其进行模板化;

template <typename U = T>
std::void_t<decltype(U::value)> print()
 { std::cout << parameter.value << std::endl; }

或者也

template <typename U = T>
std::void_t<decltype(U::value), std::enable_if_t<std::is_same_v<U, T>>> 
    print()
 { std::cout << parameter.value << std::endl; }

如果你想确保没有人可以"劫持"解释模板类型调用的方法

testClass<paramtype3>{}.print<paramtype1>():

我个人要做的是排除使用某些类型的权限:

template <class T, class... Ts>
struct is_any : std::disjunction<std::is_same<T, Ts>...> {};
// https://stackoverflow.com/questions/17032310/how-to-make-a-variadic-is-same
template <typename T>
void do_something() {
    static_assert(!is_any<T, int, bool>::value, "do_something<T> cannot be used with T as int or bool");
    // code here
}

允许您添加自定义断言消息 aswel,以便轻松发现问题所在。

相关内容

  • 没有找到相关文章

最新更新