有什么办法可以部分实例化c ++模板

时间:2018-12-21 03:26:17

标签: c++ c++11 templates template-specialization

我有某种类型的模板,并且模板中的某些代码并非对所有类型都有效,因此我想在需要时跳过它们。

struct T1
{
    int getData(){return 1;}
};

struct T2
{
    string getData(){return "string";}
};

struct T3
{
    // no getData()
};

template<typename T>
void printData(T param)
{
    cout << param.getData() << endl;
}

int main() {

    T1 t1;
    T2 t2;
    T3 t3;

    printData(t1);
    printData(t2);
    printData(t3);  // fails for T3 has no getData
}

我想知道是否有这种方法(伪代码):

template<typename T>
void printData(T param)
{
    if(T != T3) // compile time check, instance on this condition
    {
        cout << param.getData() << endl;
    }
}

我尝试了std::is_same,但没有成功

2 个答案:

答案 0 :(得分:5)

从C ++ 17开始,您可以使用if constexpr (!std::is_same_v<T, T3>),如Songyuanyao的答案中所述。

在C ++ 11 / C ++ 14中,我提出了两种方法。

(1)标签分发

template <typename T>
void printData (T param, std::true_type)
 { }

template <typename T>
void printData (T param, std::false_type)
 { std::cout << param.getData() << std::endl; }

template <typename T>
void printData (T param)
 { printData(param, std::is_same<T, T3>{}); }

(2)SFINAE

// ever enabled
template <typename T>
void printData (T param, long)
 { }

// preferred (int instead of long) but enabled only
// when param support getData()
template <typename T>
auto printData (T param, int)
   -> decltype( param.getData(), void() )
 { std::cout << param.getData() << std::endl; }

template <typename T>
void printData (T param)
 { printData(param, 0); }

答案 1 :(得分:2)

问题在于,当TT3时,仍然会在编译时评估statement_true,这会导致编译错误。

您可以使用Constexpr If(自C ++ 17起)。

  

如果值为true,则丢弃statement-false(如果存在),否则,丢弃statement-true。

例如

if constexpr (!std::is_same_v<T, T3>)
{
    cout << param.getData() << endl;
}