2015-07-17 3 views
1

Рассмотрима следующего упрощенного кода для функтора обертки:«недопустимое использование неполного типа» для сопзЬ типа указателя на функцию в качестве аргумента шаблона

#include <iostream> 
#include <utility> // std::forward 

template <class F> 
struct return_type; 

template <class R, class C, class... A> 
struct return_type <R (C::*)(A...)> { 
    typedef R type; 
}; 

// ---------------------- 

template <class FunctorType, typename FunctionPointerType> 
class functor_wrapper { 
public: 
    FunctorType* f; 
    FunctionPointerType p; 
    functor_wrapper (FunctionPointerType pp) : p(pp) { f = new FunctorType; } 

    template <class... A> 
    typename return_type<FunctionPointerType>::type operator() (A && ... args) { 
     return ((f->*p) (std::forward<A>(args)...)); 
    } 
}; 

// ---------------------- 

class my_less { 
public: 
    bool non_const_mem (const int& x, const int& y) {return x<y;} 
    bool const_mem (const int& x, const int& y) const {return x<y;} 
}; 

// ---------------------- 

int main(int argc, char *argv[]) 
{ 
    // functor_wrapper <my_less, bool (my_less::*)(const int&, const int&)> foo(&my_less::non_const_mem); // OK!! 
    functor_wrapper <my_less, bool (my_less::*)(const int&, const int&) const> foo(&my_less::const_mem); // ERROR!! 
                    // ^^^^ 
    std::cout << "is 2<5? " << (foo(2,5)?"yes":"no") << std::endl; 
} 

В декларации «Foo», если я использую постоянную функцию члена Я получаю ошибку компиляции «invalid use of incomplete type ‘struct return_type<bool (my_less::*)(const int&, const int&)const>’». Однако, если это не константная функция-член, она компилируется и выполняется просто отлично. Я не понимаю, где «неполный тип» находится в этом коде, когда функция-член имеет постоянный тип и что я могу сделать, чтобы заставить его работать для постоянных функций-членов?

Я использую версию gcc 4.8.4.

+0

Есть ли какой-либо причине вы не просто использовать 'зЬй :: function'? Он также работает с указателями функций-членов. – Alejandro

ответ

2

У вас не хватает подходящего квалифицированного специализации шаблона, как этот:

template <class R, class C, class... A> 
struct return_type <R (C::*)(A...) const> { 
    typedef R type;    // ^^^^^ 
}; 
+0

Вот и все! Огромное спасибо. –

Смежные вопросы