【问题标题】:Template argument deduction for inheriting specializations继承特化的模板参数推导
【发布时间】:2019-08-16 18:22:51
【问题描述】:

考虑this代码:

#include <type_traits>

template < typename > struct BB { };
template < >          struct BB<float> : BB<int> { };
                      struct DD : BB<float> { };

template < typename... Args >
void ff(BB<Args...>) { }

int main()
{
    ff(BB<float>{});
    ff(DD{}); // FAILS! 'BB<Args ...>' is an ambiguous base class of 'DD'
    return 0;
}

ff(DD{}) 的调用无法编译,因为gcc-8.3 不想从BB&lt;float&gt;BB&lt;int&gt; 中选择一个(clang 也是如此)。但是BB&lt;float&gt; isa BB&lt;int&gt;,那为什么不能只选择BB&lt;float&gt;?!

问题是:这是否符合标准?在定义ffBB 时是否有解决方法来帮助gcc-8.3 选择BB&lt;float&gt;

【问题讨论】:

  • 看起来这是一个 gcc 错误。对于它的价值,icc19 编译得很好。我看不出为什么 DD 不能转换为 BB&lt;float&gt;
  • @SergeyA:为什么编译器应该能够正确推断出这一点?怎么样?
  • 与此处相同:godbolt.org/z/bPYajH
  • @SergeyA:但是,MSVC 会处理它
  • @SergeyA:我认为 [temp.deduct.type] 同意你的观点,应该可以推导出模板参数。

标签: c++ templates inheritance language-lawyer specialization


【解决方案1】:

这个问题是CWG 2303 的主题。委员会决定添加“更喜欢'更接近'的基类”的措辞,这个措辞是added to the working draft。因此,在 C++20 中,您的示例应该实例化 ff&lt;float&gt;(BB&lt;float&gt;),而在 C++17 中,它是模棱两可的。

当然,如果您的编译器不支持“C++2a”模式或者如果 C++2a 模式尚未实现此更改,则解决方法是添加采用 @987654325 的 ff 的重载@。

【讨论】:

  • 感谢您提供正确答案,以便我删除我的版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 2013-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-19
相关资源
最近更新 更多