C++ 模板类中模板类成员的演绎
我利用C++17的新特性来推断模板类中的类成员类型。具体而言,我正在这样做:C++ 模板类中模板类成员的演绎,c++,templates,c++17,member,C++,Templates,C++17,Member,我利用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;
#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
中引入另一个模板参数时,这种魔力就被破坏了,如下所示:
template <typename T, std::size_t N = 0>
class A
{
... // same content, no use of T
}
编译器在所有情况下都推断出N=0
,并且无法将输入std::array
分配给构造函数中的推断参数std::array
:
错误:调用'A::A()'时没有匹配的函数
A a1{data};
注:候选者:'A::A(常量数组&)[带T=int;长无符号int N=0;A::Array=std::Array]'
A(const数组&arr):myArr{arr}{}
注意:参数1从'std::array'到'const-array&'{aka'const-std::array&'}没有已知的转换
A(const数组&arr):myArr{arr}{}
有谁能解释一下为什么会发生这种情况,以及是否有解决办法
提前谢谢你 扣减指南不进行部分匹配 合成与否 在第一种情况下,编译器合成演绎指南
template<std::size_t N>
A(std::array<int,N>const&)->A<N>;
模板
A(std::arrayconst&)->A;
传递任何模板参数后,将不使用扣减指南。没有部分匹配
请参阅,以获得您所称的魔法的合理描述
如果需要,可以编写make函数,或者省略int
至于原因,可能是反向兼容性和KISS原则。当您键入
A
时,您指定了所有模板参数,N默认为0。没有推论。@S.M.就是这样!我没有意识到。那么我认为没有办法正确推断出N
,我需要在任何地方传递T
,这是否回答了你的问题@大卫谢林:谢谢,这是一个非常接近的答案,但我想我不能让它在我的情况下工作。如果我为N=0
的情况声明template class A->A
,那么我可以在模板class A
中删除N
的默认值。这很好,它将允许a2代码>。然而,我不知道如何声明N>0
的情况,而不显式地指示a1{data}代码>。有可能吗?或者我错过了什么吗?@Victor:我投票支持复制品是基于它对困难的解释,而不是它的变通方法的适用性。这并不是说没有:例如,在C++20中,您可以使用类似于wrapper::alias a{data}的东西代码>。
A<int> a1{data};
A<int> a2;
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} {}
template<std::size_t N>
A(std::array<int,N>const&)->A<N>;