C语是正确的。 [namespace.udecl]/14:
(肺hp矿)
当using-declarator将基类中的声明带入
派生类,成员函数和成员函数模板
派生类重写和/或隐藏成员函数和成员
具有相同名称,parameter-type-list,
基本类别中的cv-qualification和ref-qualifier(如果有)
而不是冲突。此类隐藏或覆盖的声明不包括在内
来自using-declarator引入的一组声明。
这意味着,在这种情况下,foo
的继承构造函数模板被Bar
的构造函数模板隐藏。请注意,即使是模板,也只考虑名称,parameter-type-list,cv-qualification和ref-qualifier。
,
添加第二个模板参数和默认参数后,
Clang不会继承构造函数模板。另一方面,在函数的参数列表(C ++ 03样式)中使用SFINAE构造没有问题:
struct Foo {
Foo() = default;
template<typename T>
Foo(T& object,std::enable_if_t<std::is_trivially_copyable_v<T>>* = nullptr) {}
};
struct Bar : public Foo {
using Foo::Foo;
template<typename T>
Bar(T& object,std::enable_if_t<!std::is_trivially_copyable_v<T>>* = nullptr) {}
};
Live example
在此版本中,构造函数模板可以很好地继承,并可以像预期的那样用于重载解析。
将自己的SFINAE检查移到c'tor的参数中,而不更改Foo
似乎也可以解决该问题:
struct Foo {
Foo() = default;
template<typename T,std::enable_if_t<std::is_trivially_copyable_v<T>>* = nullptr>
Foo(T& object) {}
};
struct Bar : public Foo {
using Foo::Foo;
template<typename T>
Bar(T& object,std::enable_if_t<!std::is_trivially_copyable_v<T>>* = nullptr) {}
};
Live example
Clang认为原始模板的签名与基类中的签名相同。因此,它认为隐藏了基类版本。
本文链接:https://www.f2er.com/3161764.html