有没有办法编写多态模板函数?

时间:2017-05-22 12:32:15

标签: c++ c++11 templates

假设我有一个功能

template <typename T>
T foo() {
    // do stuff  
    return T(/* some value*/);
}

所以我可以这样称呼它:

int my_int = foo<int>();
std::string my_string = foo<std::string>();

有没有办法让我创建2个单独的多态函数,这样我就可以拥有一个仅在Tstd::string时才被调用的函数?

我尝试使用以下代码执行此操作:

template <typename T>
T foo() {
    if (std::is_same<std::string, T>::value) {
       // do string specific stuff

    }

    return T(/* some value */);
}

但是,如果T std::string T fooString()在其他类型INNER JOIN时无法正常运行,我会收到编译错误。有没有办法使这个多态,或者我应该使用不同的函数名称,如SELECT COUNT(mes.subject) total_msg FROM subjects sub INNER JOIN messages mes on mes.subject_id = sub.id

2 个答案:

答案 0 :(得分:3)

您可以使用模板专业化:

template <typename T>
T foo() { //v1
    return T(/* some value */);
}

template <>
std::string foo() { // v2
    return "Hello World !";
}

使用字符串调用(作为模板参数)时,将调用foo的版本2。否则它是版本1.

修改

查看@BartekBanachewicz对该问题的评论,了解为什么不应该使用功能模板专业化。

答案 1 :(得分:3)

您可以使用SFINAE

#include <complex>
#include <iostream>
#include <type_traits>

template <typename T>
typename std::enable_if<false == std::is_same<T, std::string>::value, T>::type
      foo ()
 {
   std::cout << "- generic foo()" << std::endl;

   return T{};
 }

template <typename T>
typename std::enable_if<true == std::is_same<T, std::string>::value, T>::type
      foo ()
 {
   std::cout << "- std::string foo()" << std::endl;

   return T{""};
 }

int main()
 {
   foo<int>();                       // print - generic foo()
   foo<std::complex<long double>>(); // print - generic foo()
   foo<std::string>();               // print - std::string foo()
 }