Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板类中模板类成员的演绎_C++_Templates_C++17_Member - Fatal编程技术网

C++ 模板类中模板类成员的演绎

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;

我利用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
中引入另一个模板参数时,这种魔力就被破坏了,如下所示:

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