在C ++ 11中,我实现了用于识别继承的函数模板特化,但它发生了编译时错误。
f()
检查指定的类是否派生自Base
。
以下是源代码。
#include <iostream>
#include <type_traits>
using namespace std;
struct Base {};
struct Derived : Base {};
struct Base2 {};
template<typename T, bool = std::is_base_of<Base, T>::value>
void f() {
cout << "T is not Base or Base-derived class." << endl;
};
template<typename T>
void f<T, true>() {
cout << "T is Base or Base-derived class." << endl;
};
int main() {
f<Base>(); // ok
f<Derived>(); // ok
f<Base2>(); // not ok
return 0;
}
以下是错误消息。
prog.cpp:15:17: error: non-class, non-variable partial specialization 'f<T, true>' is not allowed
void f<T, true>() {
^
prog.cpp: In function 'int main()':
prog.cpp:20:13: error: call of overloaded 'f()' is ambiguous
f<Base>();
^
prog.cpp:10:6: note: candidate: void f() [with T = Base; bool <anonymous> = true]
void f() {
^
prog.cpp:15:6: note: candidate: void f() [with T = Base]
void f<T, true>() {
^
prog.cpp:21:16: error: call of overloaded 'f()' is ambiguous
f<Derived>();
^
prog.cpp:10:6: note: candidate: void f() [with T = Derived; bool <anonymous> = true]
void f() {
^
prog.cpp:15:6: note: candidate: void f() [with T = Derived]
void f<T, true>() {
^
prog.cpp:22:14: error: call of overloaded 'f()' is ambiguous
f<Base2>();
^
prog.cpp:10:6: note: candidate: void f() [with T = Base2; bool <anonymous> = false]
void f() {
^
prog.cpp:15:6: note: candidate: void f() [with T = Base2]
void f<T, true>() {
^
我该如何解决?
答案 0 :(得分:0)
当std::is_base_of<Base, T>::value
评估true
时,您有两个具有相同签名的函数。因此,您会收到错误“call ... is amibguous”。
尝试简单重载作为解决方案之一:
namespace detail {
void doIt(std::false_type) {
cout << "T is not Base or Base-derived class." << endl;
};
void doIt(std::true_type) {
cout << "T is Base or Base-derived class." << endl;
};
}
template<typename T>
void f() {
detail::doIt(typename std::is_base_of<Base, T>::type());
};
当然,函数detail::doIt()
可能更复杂,也可能被T模板化。
编辑:将"detail::"
添加到函数f()
调用中。