Class 派生的 class 模板参数推导失败
Class template argument deduction failed with derived class
#include <utility>
template<class T1, class T2>
struct mypair : std::pair<T1, T2>
{ using std::pair<T1, T2>::pair; };
int main()
{
(void)std::pair(2, 3); // It works
(void)mypair(2, 3); // It doesn't work
}
上面的格式是否正确?
如果构造函数被继承,是否可以在第二种情况下推导出 class 模板参数? std::pair
的构造函数是否参与了 mypair
的隐式推导指南的创建?
我的编译器是 g++ 7.2.0。
参见。
此答案的先前版本指出以下应该有效
template <class T> struct B { B(T ) { } };
template <class T> struct D : B<T> { using B<T>::B; };
B b = 4; // okay, obviously
D d = 4; // expected: okay
但这并不是真正可行的,甚至不是像我想象的那样工作的好主意(我们继承了构造函数而不是演绎指南?)
简短的故事:标准中没有规则说明这将如何工作,也没有任何规则说明它不起作用。所以 GCC 和 Clang 保守地拒绝而不是发明一个 (non-standard) 规则。
长话短说: mypair
的 pair
基础 class 是依赖类型,因此查找其构造函数无法成功。对于mytype<T1, T2>
的每个特化,pair<T1, T2>
的相应构造函数是mytype
的构造函数,但这不是可以有意义地应用于的规则一般实例化之前的模板。
原则上,可能有一条规则说在这种情况下您要查看主 pair
模板的构造函数(就像我们在查找 mypair
本身的构造函数时所做的一样class template argument deduction),但目前标准中实际上没有这样的规则。但是,当基础 class 变得更加复杂时,这样的规则很快就会失效:
template<typename T> struct my_pair2 : std::pair<T, T> {
using pair::pair;
};
理论上应该在此处注入哪些构造函数?在这种情况下,我认为很明显这种查找不可能起作用:
template<typename T> struct my_pair3 : arbitrary_metafunction<T>::type {
using arbitrary_metafunction<T>::type::type;
};
我们可能会更改规则以允许通过您的 my_pair
和 if/when 上面的 my_pair2
进行推导,我们得到 class 别名的模板参数推导规则模板:
template<typename T> using my_pair3 = std::pair<T, T>;
my_pair3 mp3 = {1, 2};
这里涉及的复杂性在很大程度上与继承构造函数的情况相同。 Faisal Vali(class 模板参数推导的其他设计者之一)有一个关于如何使这种情况起作用的具体计划,但 C++ 委员会尚未讨论此扩展。
#include <utility>
template<class T1, class T2>
struct mypair : std::pair<T1, T2>
{ using std::pair<T1, T2>::pair; };
int main()
{
(void)std::pair(2, 3); // It works
(void)mypair(2, 3); // It doesn't work
}
上面的格式是否正确?
如果构造函数被继承,是否可以在第二种情况下推导出 class 模板参数? std::pair
的构造函数是否参与了 mypair
的隐式推导指南的创建?
我的编译器是 g++ 7.2.0。
参见
此答案的先前版本指出以下应该有效
template <class T> struct B { B(T ) { } };
template <class T> struct D : B<T> { using B<T>::B; };
B b = 4; // okay, obviously
D d = 4; // expected: okay
但这并不是真正可行的,甚至不是像我想象的那样工作的好主意(我们继承了构造函数而不是演绎指南?)
简短的故事:标准中没有规则说明这将如何工作,也没有任何规则说明它不起作用。所以 GCC 和 Clang 保守地拒绝而不是发明一个 (non-standard) 规则。
长话短说: mypair
的 pair
基础 class 是依赖类型,因此查找其构造函数无法成功。对于mytype<T1, T2>
的每个特化,pair<T1, T2>
的相应构造函数是mytype
的构造函数,但这不是可以有意义地应用于的规则一般实例化之前的模板。
原则上,可能有一条规则说在这种情况下您要查看主 pair
模板的构造函数(就像我们在查找 mypair
本身的构造函数时所做的一样class template argument deduction),但目前标准中实际上没有这样的规则。但是,当基础 class 变得更加复杂时,这样的规则很快就会失效:
template<typename T> struct my_pair2 : std::pair<T, T> {
using pair::pair;
};
理论上应该在此处注入哪些构造函数?在这种情况下,我认为很明显这种查找不可能起作用:
template<typename T> struct my_pair3 : arbitrary_metafunction<T>::type {
using arbitrary_metafunction<T>::type::type;
};
我们可能会更改规则以允许通过您的 my_pair
和 if/when 上面的 my_pair2
进行推导,我们得到 class 别名的模板参数推导规则模板:
template<typename T> using my_pair3 = std::pair<T, T>;
my_pair3 mp3 = {1, 2};
这里涉及的复杂性在很大程度上与继承构造函数的情况相同。 Faisal Vali(class 模板参数推导的其他设计者之一)有一个关于如何使这种情况起作用的具体计划,但 C++ 委员会尚未讨论此扩展。