如何解决 C++ 中的多重继承歧义
How to resolve multiple inheritance ambiguities in C++
我有一个小程序如下:
#include <iostream>
template <typename T>
class X{
public:
bool something(){
return true;
}
};
class A: public X<A>{
};
class B: public A, public X<B>{
};
template <typename T>
bool use(T &t)
{
return t.something();
}
int main()
{
B b;
std::cout << "use returned: " << use(b);
}
这将无法编译,因为对于应该选择 something()
的两个可能版本中的哪一个存在歧义:
In instantiation of 'bool use(T&) [with T = B]':
30:43: required from here
22:20: error: request for member 'something' is ambiguous
6:14: note: candidates are: bool X<T>::something() [with T = B]
6:14: note: bool X<T>::something() [with T = A]
In function 'bool use(T&) [with T = B]':
23:1: warning: control reaches end of non-void function [-Wreturn-type]
我的问题是,如果我唯一可以编辑的地方是 use()
的正文,我该如何解决这个歧义?
是的。例如,您可以限定对 something
(godbolt):
的调用
template <typename T>
bool use(T &t)
{
return t.A::something();
}
对于 T 从 X 派生然后在内部转换为 X 的情况,您可以添加模板“use”的特化。
template <typename T>
class X{
public:
bool something(){
return true;
}
};
class A: public X<A>{
};
class B: public A, public X<B>{
};
#
# If class derives from X<T> make sure to cast to X<T> before calling something
#
template<typename T>
typename std::enable_if<std::is_base_of<X<T>, T>::value, bool>::type use(T &t)
{
return static_cast<X<T>&>(t).something();
}
#
# This gets run for everything that doesn't derive from X<T>
#
template<typename T>
typename std::enable_if<!std::is_base_of<X<T>, T>::value, bool>::type use(T &t)
{
return t.something();
}
虽然必须检查语法,但这应该确保您在特殊情况下得到它,同时只允许一次“某事”调用。
我有一个小程序如下:
#include <iostream>
template <typename T>
class X{
public:
bool something(){
return true;
}
};
class A: public X<A>{
};
class B: public A, public X<B>{
};
template <typename T>
bool use(T &t)
{
return t.something();
}
int main()
{
B b;
std::cout << "use returned: " << use(b);
}
这将无法编译,因为对于应该选择 something()
的两个可能版本中的哪一个存在歧义:
In instantiation of 'bool use(T&) [with T = B]': 30:43: required from here 22:20: error: request for member 'something' is ambiguous 6:14: note: candidates are: bool X<T>::something() [with T = B] 6:14: note: bool X<T>::something() [with T = A] In function 'bool use(T&) [with T = B]': 23:1: warning: control reaches end of non-void function [-Wreturn-type]
我的问题是,如果我唯一可以编辑的地方是 use()
的正文,我该如何解决这个歧义?
是的。例如,您可以限定对 something
(godbolt):
template <typename T>
bool use(T &t)
{
return t.A::something();
}
对于 T 从 X 派生然后在内部转换为 X 的情况,您可以添加模板“use”的特化。
template <typename T>
class X{
public:
bool something(){
return true;
}
};
class A: public X<A>{
};
class B: public A, public X<B>{
};
#
# If class derives from X<T> make sure to cast to X<T> before calling something
#
template<typename T>
typename std::enable_if<std::is_base_of<X<T>, T>::value, bool>::type use(T &t)
{
return static_cast<X<T>&>(t).something();
}
#
# This gets run for everything that doesn't derive from X<T>
#
template<typename T>
typename std::enable_if<!std::is_base_of<X<T>, T>::value, bool>::type use(T &t)
{
return t.something();
}
虽然必须检查语法,但这应该确保您在特殊情况下得到它,同时只允许一次“某事”调用。