有没有办法部分实例化一个c ++模板

mai*_*mai 3 c++ templates template-specialization c++11

我有一个类型的模板,模板中的一些代码对所有类型都无效,所以我想在需要时跳过它们.

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
}
Run Code Online (Sandbox Code Playgroud)

我想知道是否有这样的方式(伪代码):

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

我试过std::is_same但它没有用

max*_*x66 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>{}); }
Run Code Online (Sandbox Code Playgroud)

(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); }
Run Code Online (Sandbox Code Playgroud)