【问题标题】:C++ primer 5th edition: C++ template class arguments deductionC++入门第5版:C++模板类参数推导
【发布时间】:2020-10-27 22:30:50
【问题描述】:

再次使用 C++ 入门 5 版第 16 章:模板。

在书中:

“类模板是生成类的蓝图。类模板与函数模板的不同之处在于编译器无法推断出类模板的模板参数类型。相反,正如我们多次看到的那样,使用一个类模板,我们必须在模板名称后面的尖括号内提供额外信息(第 3.3 节,第 97 页)。这些额外信息是用于代替模板参数的模板参数列表。”

但我认为这是不正确的:如果模板类有一个带有一些依赖类型参数的构造函数,那么如果我用该构造函数定义一个对象,编译器就可以推断出模板参数。例如:

template <typename T>
class Add
{
public:
    Add() = default;
    Add(T const&, T const&);
    T operator ()(T const&, T const&)const;
};

template <typename T>
Add<T>::Add(T const& lhs, T const& rhs){}

template <typename T>
T Add<T>::operator()(T const& lhs, T const& rhs)const
{
    return lhs + rhs;
}

int main()
{

    Add(5, 7); // the compiler can deduce template arguments here.
    std::cout << Add(0, 0)(7, 5) << '\n'; // 12

    Add a(1, 2); // ok
    std::cout << a(5, -1) << '\n'; // 4 ok

    std::cout << "\ndone!\n";
}
  • 我说的对吗?我已经根据不同的 c++ 标准编译了代码并且工作正常。

【问题讨论】:

  • 原语句是编译器需要能够推导出来的,所以必须提供额外的信息。用法是附加信息。在某些情况下,构造函数的用法不提供此功能,您必须明确提供它。 C++ 编译器在跟踪这些使用信息方面变得越来越聪明,因此严格的定义可能不再适用。
  • 那么他说的模板函数和模板类有什么区别呢? “类模板与函数模板的不同之处在于编译器无法推断类模板的模板参数类型。”
  • 在最广泛的意义上他们不能,但在特定情况下他们可以。如果您有一个具有从不公开的模板类型内部的类,则无法通过使用来推断它。您必须明确指定它们。
  • @tadman:您现在对​​书中的内容有何看法:“我们现在可以看到,额外的信息是绑定到模板参数的显式模板参数列表。编译器使用这些从模板实例化特定类的模板参数。例如,要从我们的 Blob 模板定义类型,我们必须提供元素类型: Blob ia; // empty Blob Blob ia2 = { 0,1,2,3,4}; // 带有五个元素的 Blob" 但是如果我从 ia2 中删除 int 它可以正常工作,但不是 ia。据说必须是显式的。
  • 第二种形式没有该类型信息是不明确的。

标签: c++ templates template-argument-deduction


【解决方案1】:

那是因为 CTAD 在 C++17 中。

C++ Primer 可能不涉及 C++14/17/20 的新特性。你可以参考https://en.cppreference.com/w/cpp来确认这些功能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-04
    • 2021-12-08
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    • 2021-08-25
    • 2021-11-24
    相关资源
    最近更新 更多