在派生 class 中重载模板运算符
Overloading template operator in derived class
给定一个基 class 和一个派生 class,它们都使用 SFINAE 为特定参数类型提供有条件启用的运算符:
#include <type_traits>
class Base
{
public:
template<class T, std::enable_if_t<std::is_scalar_v<T>>* = nullptr>
void operator>>(T& value) {
}
};
class Derived: public Base
{
public:
using Base::operator>>;
template<class T, std::enable_if_t<!std::is_scalar_v<T>>* = nullptr>
void operator>>(T& value) {
}
};
int main(int argc, char *argv[])
{
int foo;
Base base;
base >> foo; // this works
Derived derived;
derived >> foo; // this doesn't work, the operator from the base class is not considered
}
然后在派生 class 的实例上调用基 class 中定义的运算符将不起作用,即使它应该已通过适当的 using Base::operator>>;
声明可见.为什么?如何在不冗长地重复 declaration/definition 的情况下使基础 class 中的运算符可用?
如果有问题的运算符不是基础中的模板,则不会出现此问题 class。
编辑:使用 msvc 15.9.7 和 clang 进行测试。
我认为这里的问题是 using 声明仅将函数和函数模板的声明带入派生 class 中,派生 class 具有未被派生 class 成员覆盖的签名 [namespace.udecl]/15。所以这段代码确实应该编译不通过。
使用自由函数代替 class 成员来解决问题:
#include <type_traits>
class Base
{
public:
template<class T, std::enable_if_t<std::is_scalar_v<T>>* = nullptr>
friend void operator>>(Base&, T& value) {
}
};
class Derived: public Base
{
public:
template<class T, std::enable_if_t<!std::is_scalar_v<T>>* = nullptr>
friend void operator>>(Derived&, T& value) {
}
};
int main()
{
int foo;
Base base;
base >> foo;
Derived derived;
derived >> foo;
}
给定一个基 class 和一个派生 class,它们都使用 SFINAE 为特定参数类型提供有条件启用的运算符:
#include <type_traits>
class Base
{
public:
template<class T, std::enable_if_t<std::is_scalar_v<T>>* = nullptr>
void operator>>(T& value) {
}
};
class Derived: public Base
{
public:
using Base::operator>>;
template<class T, std::enable_if_t<!std::is_scalar_v<T>>* = nullptr>
void operator>>(T& value) {
}
};
int main(int argc, char *argv[])
{
int foo;
Base base;
base >> foo; // this works
Derived derived;
derived >> foo; // this doesn't work, the operator from the base class is not considered
}
然后在派生 class 的实例上调用基 class 中定义的运算符将不起作用,即使它应该已通过适当的 using Base::operator>>;
声明可见.为什么?如何在不冗长地重复 declaration/definition 的情况下使基础 class 中的运算符可用?
如果有问题的运算符不是基础中的模板,则不会出现此问题 class。
编辑:使用 msvc 15.9.7 和 clang 进行测试。
我认为这里的问题是 using 声明仅将函数和函数模板的声明带入派生 class 中,派生 class 具有未被派生 class 成员覆盖的签名 [namespace.udecl]/15。所以这段代码确实应该编译不通过。
使用自由函数代替 class 成员来解决问题:
#include <type_traits>
class Base
{
public:
template<class T, std::enable_if_t<std::is_scalar_v<T>>* = nullptr>
friend void operator>>(Base&, T& value) {
}
};
class Derived: public Base
{
public:
template<class T, std::enable_if_t<!std::is_scalar_v<T>>* = nullptr>
friend void operator>>(Derived&, T& value) {
}
};
int main()
{
int foo;
Base base;
base >> foo;
Derived derived;
derived >> foo;
}