9

我遇到了这段代码(我试图包括所有细节,以防我遗漏了什么):

template< typename TYPE = TYPE_with_an_arbitrarily_long_name,
          typename KIND = KIND_with_an_arbitrarily_long_name>

class Foo
{
public:
    virtual void bar(TYPE& t, KIND& k) = 0;
};

我不明白的部分是模板内的分配:

template <typename TYPE = TYPE_with_an_arbitrarily_long_name, ..

我一直在试图了解它的影响,但到目前为止我无法产生任何效果。以下是我尝试过的一些东西:

#include <iostream>
#include <typeinfo>
using namespace std;

template<typename T>
void foo(T t) {
    cout << typeid(t).name() << " ";
}

template<typename T = int>
void bar(T t) {
    cout << typeid(t).name() << " ";
}

template<typename T = double>
void baz(T t) {
    cout << typeid(t).name() << " ";
}

int main()
{
    cout << "\nfoo: ";
    foo(3); foo<int>(3); foo<double>(3);
    cout << "\nbar: ";
    bar(3); bar<int>(3); bar<double>(3);
    cout << "\nbaz: ";
    baz(3); baz<int>(3); baz<double>(3);
    return 0;
}

打印出来:

foo: i i d
bar: i i d
baz: i i d

所以我的问题是:

  1. 里面赋值有什么作用template
  2. 在上面的例子中使用它的目的是什么?
  3. 没有第三个问题。

任何帮助表示赞赏..

编辑结果函数只能用 c++11 编译

4

6 回答 6

8

这称为“默认模板参数”,并指定使用哪种类型,当没有指定时 - 类似于默认函数参数。这种技术广泛用于类 - 查看std::vectoror的定义std::string,您会发现它们有多个默认类型参数。

函数模板的默认类型参数的最佳用途是当类型参数不能轻易地从实际参数中推断出来,并且没有明确指定时 - 然后编译器将使用默认值。在您的示例中,不需要默认类型,因为它可以很容易地从实际调用参数中推断出来。

直到 C++0x 的默认类型参数只允许用于类模板——它们不能与函数模板一起使用。使用 C++0x 时它发生了变化,但一些较旧的编译器(例如 Visual C++ 2008)不允许您使用它们。

于 2012-11-26T14:00:36.573 回答
7

这些不是赋值,而是模板类型参数的“默认值”,就像函数的默认值参数有类似的语法一样。当未指定显式参数时使用它们。

对于您的示例中barbaz函数模板,它没有任何意义,因为对于这些函数,T将派生自指定的参数。

于 2012-11-26T13:58:58.787 回答
6

函数模板可能不是演示默认模板参数的最佳构造。这与模板结构类似:

#include <iostream>
#include <typeinfo>

template<typename T = int>
struct foo {
   static void f() {
      std::cout << typeid(T).name() << "\t";
   }
};

template<typename T = double>
struct bar {
   static void f() {
      std::cout << typeid(T).name() << "\t";
   }
};

int main() {
  foo<>::f(); foo<int>::f();  foo<double>::f();  std::cout << std::endl;
  bar<>::f(); bar<int>::f();  bar<double>::f();  std::cout << std::endl;
}

运行这个,我得到:

% ./a.out 
i   i   d   
d   i   d   
于 2012-11-26T14:00:12.773 回答
2
  1. 模板参数列表中的“赋值”是默认参数,就像在函数参数列表中一样。这意味着在您的示例中,Foo<>与 相同Foo<TYPE_with_an_arbitrarily_long_name, KIND_with_an_arbitrarily_long_name>,并且Foo<int>与 相同Foo<int, KIND_with_an_arbitrarily_long_name>
  2. 它不会在您的示例中使用。您根本不使用Foo,并且 和 的参数bazbar始终由编译器从给定的参数中推导出来。
于 2012-11-26T14:02:27.687 回答
1

这些是默认模板参数。您可以使用模板默认参数来简化它们的使用。

例如,当您有两个模板参数并为最后一个参数指定默认类型时,您必须只指定一种类型。

std::vector,例如,定义为

template < class T, class Allocator = allocator<T> > class vector;

这里你有一个默认的模板参数Allocator,所以你可以只用一个参数定义向量

std::vector<int> v;
于 2012-11-26T14:01:41.970 回答
-3

您正在寻找的是“模板专业化”

这是一些示例/说明的链接

于 2012-11-26T14:00:11.903 回答