隐式模板参数

时间:2011-02-09 16:00:20

标签: c++ xcode templates implicit

以下代码在Xcode中生成编译错误:

template <typename T>
struct Foo
{
    Foo(T Value)
    {
    }
};

int main()
{
    Foo MyFoo(123);
    return 0;
}

error: missing template arguments before 'MyFoo'

Foo MyFoo(123);更改为Foo<int> MyFoo(123);可以解决问题,但编译器是否应该找不到合适的数据类型?

这是编译器错误,还是我误解了隐式模板参数?

7 个答案:

答案 0 :(得分:11)

理论上,构造函数可以推断它正在构造的对象的类型,但声明:

Foo MyFoo(123);

MyFoo分配临时空间,并且必须知道MyFoo的完全限定类型才能知道需要多少空间。

如果您想避免键入(即用手指)特定复杂模板的名称,请考虑使用typedef

typedef std::map<int, std::string> StringMap;

或者在C ++ 0x中,您可以使用auto关键字让编译器使用类型推断 - 尽管许多人认为这会导致代码性能降低,容易出错,我自己就是这样。 ; P

答案 1 :(得分:7)

编译器只能为模板化函数计算模板参数类型,而不能用于类/结构

答案 2 :(得分:2)

这不是一个错误,它是不存在的功能。您必须在实例化期间完全指定类/结构模板参数,始终不会推断类型,因为它们可以用于函数模板。

答案 3 :(得分:2)

编译器可以推导出模板参数这样的情况:

template<typename T>
void fun(T param)
{
    //code...
}

fun(100);    //T is deduced as int;
fun(100.0);  //T is deduced as double
fun(100.0f); //T is deduced as float

Foo<int> foo(100);
fun(foo);    //T is deduced as Foo<int>;

Foo<char> bar('A');
fun(bar);    //T is deduced as Foo<char>;

实际上模板参数演绎是一个很大的话题。在ACCU阅读这篇文章:

The C++ Template Argument Deduction

答案 4 :(得分:2)

在C ++ 11中,您可以使用decltype

int myint = 123;
Foo<decltype(myint)> MyFoo(myint);

答案 5 :(得分:1)

您正在尝试执行的操作现在可以在C ++ 17中使用。可以在C ++ 17中推断模板参数。

template <typename T>
struct Foo
{
    Foo(T Value)
    {
    }
};

int main()
{
    Foo a(123);
    Foo b = 123;
    Foo c {123};
    return 0;
}

答案 6 :(得分:0)

很有意义就是这样,因为Foo不是一个类,只有Foo<T>,其中T是一个类型。

在C ++ 0x中你可以使用auto,你可以创建一个函数让你成为Foo,让我们称之为foo(小写f)。然后你会做

template<typename T> Foo<T> foo(int x)
{
  return Foo<T>(x);
}

auto myFoo = foo(55);