继承的函数模板专门化

时间:2016-02-09 07:18:00

标签: c++11 inheritance overloading

在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>() {
      ^

我该如何解决?

1 个答案:

答案 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()调用中。