模板中typename赋值的目的是什么

时间:2012-11-26 13:52:20

标签: c++ templates

我遇到过这段代码(我试图包含所有细节,以防我遗漏某些内容):

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. 没有第三个问题。
  4. 感谢任何帮助..

    编辑结果是函数只能与c ++ 11一起编译

6 个答案:

答案 0 :(得分:8)

这称为“默认模板参数”,指定在未指定时使用的类型 - 类似于默认函数参数。此技术广泛用于类 - 查看std::vectorstd::string的定义,您将看到它们有多个默认类型参数。

函数模板的默认类型参数的最佳用途是,无法从实际参数中轻松推导出类型参数,并且未明确指定 - 然后编译器将使用默认参数。在您的示例中,不需要默认类型,因为它可以从实际调用参数中轻松推断出来。

直到C ++ 0x默认类型参数仅允许用于类模板 - 它们不能用于函数模板。随着C ++ 0x的改变,但是一些较旧的编译器(例如Visual C ++ 2008)不允许你使用它们。

答案 1 :(得分:7)

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

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

答案 2 :(得分: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   

答案 3 :(得分: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的参数。

答案 4 :(得分:1)

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

例如,如果您有两个模板参数,并且为最后一个提供默认类型,则必须仅指定一种类型。

例如,

std::vector被定义为

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

这里有Allocator的默认模板参数,因此您可以使用一个参数定义向量

std::vector<int> v;

答案 5 :(得分:-3)

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

以下是指向某些Example/Explanation

的链接