【问题标题】:How to force compiler to deduce a class template argument?如何强制编译器推断出类模板参数?
【发布时间】:2019-04-21 22:40:29
【问题描述】:

我是 C++ 模板的新手,我(非常不成功)试图强制编译器在初始化时推断模板类型名参数。

这是我的代码。

template <typename T>
class C
{
public:
        T a;
        C(T a) : a(a) {}
        C(const C<T>& other) : a(other.a) {}
};

int main()
{
        C<int> x(1);
        C y{ x };

        return 0;
}

这段代码用g++编译会报错。

test.cpp:13:11: error: missing template arguments before ‘y’
         C y{ x };
           ^

我想保持这种语法 - 只是 C 没有明确指定模板参数。

我曾尝试使用演绎指南,但它只引发了另一个错误。

template <typename T> C(const C<T>& other) -> C<T>;

当我在 C 类的定义下方插入这一行时,我得到了这个。

test.cpp:10:51: error: expected constructor, destructor, or type conversion before ‘;’ token
 template <typename T> C(const C<T>& other) -> C<T>;
                                                   ^

当我将此行放入 C 类定义(在顶部)中时发生另一个错误。

C(const C<T>& other) -> C<T>;
test.cpp:4:26: error: ‘C’ function with trailing return type not declared with ‘auto’ type specifier
  C(const C<T>& other) -> C<T>;
                          ^~~~

在这两种情况下,第一次提及错误仍然存​​在。

谢谢!

【问题讨论】:

  • 无法重现:我使用 g++ (8.3.0) 和 clang++ (7.0.1) 编译您的原始代码,没有错误。您确定您已启用 C++17 编译吗?阅读错误消息,我怀疑您正在编译 C++14 或 C++11,并且在 C++17 中引入了推导指南。
  • 谢谢。我的错误 - 我一直在使用 g++ 8.2.0,默认情况下它是 C++14。它适用于 C++17。

标签: c++ templates type-deduction


【解决方案1】:

在 C++11 中,只有模板函数可以推导出它们的模板参数。例如,给定:

void f(std::pair<int, char> &s);

,可以这样称呼它

f(std::make_pair(5, 'c'));

,因为std::make_pair是一个函数,所以可以为函数推导出模板参数。

但是,用对调用它是非法的:

f(std::pair(5, 'c'));

,因为类模板没有模板参数推导。此问题已在 C++17 中修复,使 std::make_pair 有点过时了。

更多关于新的类模板参数推导可以找到here

为了解决您的问题,我在使用 C++11 使用 gcc 进行编译时遇到了同样的错误。代码使用 C++17 编译没有错误(对于 gcc,这可以通过传递 -std=c++17 参数来完成)。

【讨论】:

  • 谢谢。我的错误 - 我一直在使用 g++ 8.2.0,默认情况下它是 C++14。它适用于 C++17。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-13
  • 1970-01-01
相关资源
最近更新 更多