【问题标题】:Class template argument deduction failed with derived class派生类的类模板参数推导失败
【发布时间】:2018-04-04 06:48:21
【问题描述】:
#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
}

上面的格式是否正确?

如果构造函数被继承,是否可以在第二种情况下推断出类模板参数? std::pair的构造函数是否参与创建mypair的隐式推导指南?

我的编译器是 g++ 7.2.0。

【问题讨论】:

  • 使用 std::pair::pair 执行 ADL 时;被忽略
  • @HariomSingh - 你能支持一下吗?我也是那么想的。但随后 [namespace.udecl]/16.
  • @StoryTeller 是的,我正在研究这个例子。调查 ADL 的规则
  • @HariomSingh - 你会浪费你的时间。这是关于一般模板的重载解决方案。不仅仅是 ADL。
  • 现在更是如此:)

标签: c++ templates g++ c++17 template-argument-deduction


【解决方案1】:

简短的故事:标准中没有规定这将如何工作,也没有任何规定说它不起作用。因此 GCC 和 Clang 保守地拒绝而不是发明(非标准)规则。

长篇大论: mypairpair 基类是依赖类型,因此对其构造函数的查找无法成功。对于mytype&lt;T1, T2&gt; 的每个特化pair&lt;T1, T2&gt; 的相应构造函数是mytype 的构造函数,但这不是一个可以在一般实例化之前有意义地应用于模板的规则。

原则上,可能有一条规则说您在这种情况下查看主pair 模板的构造函数(就像我们在查找mypair 本身的构造函数以进行类模板参数推导时所做的那样),但目前标准中并没有这样的规则。但是,当基类变得更加复杂时,这样的规则很快就会失效:

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 和上面的my_pair2 进行推导:

template<typename T> using my_pair3 = std::pair<T, T>;
my_pair3 mp3 = {1, 2};

这里涉及的复杂性与继承构造函数的情况大致相同。 Faisal Vali(类模板参数推导的其他设计者之一)对如何使此类案例起作用有一个具体的计划,但 C++ 委员会尚未讨论此扩展​​。

【讨论】:

    【解决方案2】:

    Richard Smith's answer


    此答案的先前版本已声明以下应该工作

    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
    

    但这并不是真正可行的,甚至不会像我想的那样工作是一个好主意(我们继承了构造函数而不是推导指南?)

    【讨论】:

    • clang 对 main.cpp:10:16 都有错误:错误:如果没有模板参数列表 (void)std::pair(2, 3); 则无法引用类模板“pair”; // 它工作 ~~~~~^ /usr/include/c++/v1/utility:248:30: 注意:模板在这里声明 struct _LIBCPP_TYPE_VIS_ONLY 对 ^ main.cpp:11:11: 错误:不能引用类模板'mypair' 没有模板参数列表 (void)mypair(2, 3); // 它不起作用 ^ main.cpp:5:8: 注意:模板在这里声明 struct mypair : std::pair ^ 2 个错误生成。
    • @HariomSingh 只有 clang 5 支持类模板参数的推演,coliru 中还没有。
    • 我倾向于说这应该起作用。而且,只使用基类的构造函数而不使用它的推导指南肯定是没有意义的。
    • @Peregring-lk 我使用 clang 5.0(在 Ubuntu 16.04 上)并收到错误 no viable constructor or deduction guide for deduction of template arguments of &lt;derived class name&gt;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多