首页 > 解决方案 > 继承特化的模板参数推导

问题描述

考虑这段代码:

#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<float>BB<int>(clang做同样的事情) 中选择一个。但是BB<float> isa BB<int>,那为什么BB<float>就不能被选中呢?!

ff问题是:这是否符合标准,在定义或BB帮助gcc-8.3选择时是否有解决方法BB<float>

标签: c++templatesinheritancelanguage-lawyerspecialization

解决方案


这个问题是CWG 2303的主题。委员会决定添加“更喜欢'更接近'的基类”的措辞,并将该措辞添加到工作草案中。因此,在 C++20 中,您的示例应该实例化ff<float>(BB<float>),而在 C++17 中,它是模棱两可的。

当然,如果您的编译器不支持 "C++2a" 模式或者如果 C++2a 模式尚未实现此更改,解决方法是添加一个超载的fftake D


推荐阅读