13

以下代码在 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);解决问题,但编译器不应该能够找出适当的数据类型吗?

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

4

7 回答 7

13

构造函数理论上可以推断出它正在构造的对象的类型,但是语句:

Foo MyFoo(123);

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

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

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

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

于 2011-02-09T16:02:29.150 回答
8

编译器只能为模板化函数确定模板参数类型,而不是类/结构

于 2011-02-09T16:02:34.477 回答
2

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

于 2011-02-09T16:02:56.577 回答
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 阅读这篇文章:

C++ 模板参数推导

于 2011-02-09T16:12:39.353 回答
2

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

int myint = 123;
Foo<decltype(myint)> MyFoo(myint);
于 2015-02-21T03:14:11.080 回答
2

您现在尝试执行的操作在 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;
}
于 2019-06-07T23:12:43.010 回答
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);
于 2011-02-09T16:41:19.617 回答