【发布时间】:2021-04-21 02:42:32
【问题描述】:
我正在利用 C++17 的新功能来推断模板类中的类成员类型。具体来说,我正在这样做:
#include <array>
#include <iostream>
template <std::size_t N = 0>
class A
{
public:
using Array = std::array<int, N>;
A(const Array& arr) : myArr{arr} {}
A() = default;
void show() { std::cout << N << std::endl; }
private:
Array myArr;
};
当我构造 A 而不明确指出 N 时,编译器会正确匹配构造函数并正确推断出 N!
std::array<int, 3> data{1, 2, 3};
A a1{data};
A a2;
a1.show(); // prints 3
a2.show(); // prints 0
但是,当我在A 中引入另一个模板参数时,这个魔法就被破坏了,像这样:
template <typename T, std::size_t N = 0>
class A
{
... // same content, no use of T
}
当我像这样构造A 传递任何T 时,它不再编译:
A<int> a1{data};
A<int> a2;
编译器在所有情况下都推导出N=0,并且无法将输入std::array<int, 3>分配给构造函数std::array<int, 0>中的推导参数:
error: no matching function for call to ‘A<int>::A(<brace-enclosed initializer list>)’
A<int> a1{data};
note: candidate: ‘A<T, N>::A(const Array&) [with T = int; long unsigned int N = 0; A<T, N>::Array = std::array<int, 0>]’
A(const Array& arr) : myArr{arr} {}
note: no known conversion for argument 1 from ‘std::array<int, 3>’ to ‘const Array&’ {aka ‘const std::array<int, 0>&’}
A(const Array& arr) : myArr{arr} {}
谁能解释为什么会发生这种情况以及是否有任何解决方案?
提前谢谢你!
【问题讨论】:
-
输入
A<int>时,指定所有模板参数,N默认为0。没有推论。 -
@S.M.而已!我没有意识到。那么我相信没有办法正确推断
N,我需要到处传递T... -
@DavisHerring 谢谢,这是一个非常接近的答案,但我认为我不能让它在我的情况下工作。如果我为
N=0的情况声明template <typename T> class A -> A<T, 0>,那么我可以在template <typename T, std::size_t N> class A此处删除N的默认值。太好了,它将允许A<int> a2;。但是,我不知道如何声明N>0而不明确指出A<int, 3> a1{data};的情况。有可能还是我错过了什么? -
@Victor:我投票支持副本是基于它对困难的解释,而不是其变通方法的适用性。这并不是说不可能有:例如,在 C++20 中,您可以使用类似
wrapper<int>::alias a{data};的东西。
标签: c++ templates c++17 member