3

我有两个重载operator(),一个接受一个函数引用,该引用将任何类型作为其参数并返回任何类型。另一个接受一个函数引用,该引用将任何类型作为其参数但返回void。在实例化我的类时,我收到以下错误:

In instantiation of 'A<void, int>':
error: 'void A<T, F>::operator()(void (&)(F)) [with T = void, F = int]' cannot be overloaded
error: with 'void A<T, F>::operator()(T (&)(F)) [with T = void, F = int]'

template <typename T, typename F> struct A {
    void operator()(T (&)(F)) {}
    void operator()(void (&)(F)) {}
};

void f(int) {}

int main() {

    A<void, int> a;
    a(f);
}

这些错误仅在第一个模板参数T为时发生void。我想知道我做错了什么以及为什么我不能operator()以这种方式超载?

4

1 回答 1

7

好吧,如果T是,void那么您有两个具有完全相同原型的函数定义 - 破坏 ODR。

尝试专门化您的结构以防止这种情况:

template <typename T, typename F> struct A {
    void operator()(T (&)(F)) {}
    void operator()(void (&)(F)) {}
};

template <typename F> struct A<void, F> {
    void operator()(void (&)(F)) {}
};
于 2012-12-23T13:39:40.437 回答