`std :: enable_if` SFINAE自定义类型通过模板参数?

时间:2015-05-05 10:26:33

标签: list c++11 templates std enable-if

第一个问题:让我们说我有这样的自定义struct

struct Var {};   

struct is_var_type: std::integral_constant<bool, std::is_same<Var, typename std::remove_cv<T>::type>::value> {};

在此之后,我希望使用std::enable_if通过模板参数SFINAE获得一些自定义类型,但我无法弄明白。我只能做到这一点:

template<typename T> 
void variant(T a)
{ 
    if (is_var_type<Var>::value){
        std::cout << " " << true;
    }
    else {
        std::cout << " " << false;  
    }
}

我想制作类似这样的东西,但std::is_integral已经定义了。如何制作定制的?

template<class T, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr> // I couldn't figure out how to make custom integral_constant via template parameter 
T foo3(T t) // note, function signature is unmodified
{
    return t; //so this type should be an int, but I want to make sure that this type T is is_var_type struct, is this possible?
}

第二个问题:如果我们添加这样的容器类型,这种方法是否可行?

struct Var {};
struct ListVar: public std::list<Var>
struct is_var_type: std::integral_constant<bool, std::is_same<ListVar, typename std::remove_cv<T>::type>::value> {};

- 但是我遇到了一个更令人困惑的编译时错误,就像在gcc 4.9中无法推断多个类型一样。

1 个答案:

答案 0 :(得分:1)

我会将UserCollection3设为包裹is_var_type的模板别名。解决方案看起来像这样。

std::is_same

您也可以像在示例中一样使用#include <type_traits> // for std::decay #include <iostream> struct Var {}; // define is_var_type template<class T> using is_var_type = std::is_same<Var, typename std::decay<T>::type >; // function that works for Var template<class T , typename std::enable_if<is_var_type<T>::value>::type* = nullptr > T foo3(T t) { std::cout << " T is type Var " << std::endl; return t; } // function that works for int template<class T , typename std::enable_if<std::is_same<T,int>::value>::type* = nullptr > T foo3(T t) { std::cout << " T is type int " << std::endl; return t; } int main() { Var v; foo3(v); // calls foo3 for type Var int i; foo3(i); // calls foo3 for type int return 0; } 定义is_var_type(在定义之前缺少std::integral_constant):

template<class T>

编辑:

对于template<class T> struct is_var_type:std::integral_constant<bool,std::is_same<Var,typename std::decay<T>::type>::value > { }; 的容器,它与上面的故事相同,现在我们只检查Var是否属于T类型:

ListVar