隐式模板参数

发布于 2024-10-17 01:33:48 字数 361 浏览 1 评论 0原文

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

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

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

错误:“MyFoo”之前缺少模板参数

Foo MyFoo(123); 更改为 Foo; MyFoo(123); 解决了这个问题,但是编译器不应该能够找出适当的数据类型吗?

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

The following code generates a compile error in Xcode:

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

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

error: missing template arguments before 'MyFoo'

Changing Foo MyFoo(123); to Foo<int> MyFoo(123); fixes the issue, but shouldn't the compiler be able to figure out the appropriate datatype?

Is this a compiler bug, or am I misunderstanding implicit template parameters?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

月下凄凉 2024-10-24 01:33:48

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

Foo MyFoo(123);

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

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

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

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

The constructor could in theory infer the type of the object it is constructing, but the statement:

Foo MyFoo(123);

Is allocating temporary space for MyFoo and must know the fully-qualified type of MyFoo in order to know how much space is needed.

If you want to avoid typing (i.e. with fingers) the name of a particularly complex template, consider using a typedef:

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

Or in C++0x you could use the auto keyword to have the compiler use type inference--though many will argue that leads to less readable and more error-prone code, myself among them. ;p

痴者 2024-10-24 01:33:48

编译器只能计算出模板函数的模板参数类型,而不能计算出类/结构的模板参数类型

compiler can figure out template parameter type only for templated functions, not for classes/structs

仅此而已 2024-10-24 01:33:48

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

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++ 模板参数推导

Compiler can deduce the template argument such case:

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>;

Actually template argument deduction is a huge topic. Read this article at ACCU:

The C++ Template Argument Deduction

暮凉 2024-10-24 01:33:48

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

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

In C++11 you can use decltype:

int myint = 123;
Foo<decltype(myint)> MyFoo(myint);
脱离于你 2024-10-24 01:33:48

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

It's not a bug, it's non-existing feature. You have to fully specify class/structure template arguments during instantiation, always, the types are not inferred as they can be for function templates.

知你几分 2024-10-24 01:33:48

您现在尝试执行的操作可以在 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;
}

What you are trying to do now works in C++ 17. Template parameters can be inferred in C++ 17.

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

int main()
{
    Foo a(123);
    Foo b = 123;
    Foo c {123};
    return 0;
}
素手挽清风 2024-10-24 01:33:48

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

在 C++0x 中,您可以使用 auto,并且您可以创建一个函数来使您成为 Foo,我们将其称为 foo(小写 f)。那么你会做

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

auto myFoo = foo(55);

It makes a lot of sense it is like this, as Foo is not a class, only Foo<T> where T is a type.

In C++0x you can use auto, and you can create a function to make you a Foo, let's call it foo (lower case f). Then you would do

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

auto myFoo = foo(55);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文