功能模板的部分特化

jos*_*osh 8 c++ templates template-specialization function-templates

在下面的代码段中,

template<typename T1>
void func(T1& t)
{
    cout << "all" << endl;
}

template<typename T2>
void func(T2 &t)
{
    cout << "float" << endl;
}

// I do not want this
// template<> void func(float &t)

int main()
{
    int i; float f;
    func(i); // should print "all"
    func(f); // should print "float" 
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我希望修改模板,通过传递浮动以外的任何类型将打印"all"并传递float将打印"float".我不想要模板特化,而是根据输入类型进行相应的部分特化.我应该怎么做呢.提前致谢.

那个场景,我现在面临的是,我需要定义以下内容,

template<typename T1>
void func(T1 &t)
{
    cout << "t1" << endl;
}

template<typename T2>
void func(T2 &t)
{
    cout << "t2" << endl;
}
Run Code Online (Sandbox Code Playgroud)

以下调用应打印"t2"

func(int) // print "t2"
func(float) // print "t2"
func(string) // print "t2"
Run Code Online (Sandbox Code Playgroud)

以下调用应打印"t1"

func(char) // print "t1"
func(xyz) // print "t1"
...
func(abc) // print "t1"
Run Code Online (Sandbox Code Playgroud)

某些类似于上面的分组,很少有人应该调用部分特化实现,而其他人应该调用默认实现.

Gav*_*ock 12

您可以将函数重载与模板结合使用.所以:

#include <iostream>

template<typename T>
void func(T& t)
{
    std::cout << "all" << std::endl;
}

void func(float& f)
{
    std::cout << "float" << std::endl;
}

int main()
{
    int i; float f;
    func(i); // prints "all"
    func(f); // prints "float" 
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


Lig*_*ica 6

你不能在C++中部分专门化函数.

也许这不是你的意思.您可以使用模板boost::is_same<T1, T2>来执行基于给定模板参数的条件逻辑.您还可以T在任何其他类型的地方使用,例如typeid(T).name():

template <typename T>
void foo(T&) {
   if (boost::is_same<T, int>::value)
      std::cout << "int lol";
   else
      std::cout << typeid(T).name();
}
Run Code Online (Sandbox Code Playgroud)

(虽然我不建议使用typeid().name(),因为它的值不是由标准指定的,并且可能与代码中写入的类型,错位符号或Pokerface的歌词不同.)

附录和其他的回答者一样,我个人会选择模板专业化,或者仅仅是简单的函数重载.我不知道你为什么反对他们,但这就是他们的目的.


Fre*_*urk 6

为您的条件写一个类型特征类:

template<class T>
struct IsIntFloatOrString {
  enum { value = boost::is_same<T, int>::value
              or boost::is_same<T, float>::value
              or boost::is_same<T, string>::value };
};
Run Code Online (Sandbox Code Playgroud)

使用boost :: enable_if和disable_if:

template<typename T1>
typename boost::enable_if<IsIntFloatOrString<T1> >::type
func(T1 &t) {
  cout << "t1" << endl;
}

template<typename T2>
typename boost::disable_if<IsIntFloatOrString<T2> >::type
func(T2 &t) {
  cout << "t2" << endl;
}
Run Code Online (Sandbox Code Playgroud)