2014-01-22 1 views
2

Я встретил некоторую аналогичную проблему и нашел этот вопрос: Is it possible to figure out the parameter type and return type of a lambda?.Ошибка в функции шаблона для получения типа параметра из функции ввода в C++?

Я использую код в ответ этого вопроса:

#include <iostream> 
#include <tuple> 

template <typename T> 
struct function_traits : public function_traits<decltype(&T::operator())> {}; 

template <typename ClassType, typename ReturnType, typename... Args> 
struct function_traits<ReturnType(ClassType::*)(Args...) const> { 
    enum { arity = sizeof...(Args) }; 

    typedef ReturnType result_type; 

    template <size_t i> 
    struct arg { 
    typedef typename std::tuple_element<i, std::tuple<Args...>>::type type; 
    }; 
}; 

В моем случае функция (лямбда) определяется пользователем, так что я должен использовать шаблон функции, чтобы сделать что-то на основе пользователя -определенной функция, поэтому я добавил функцию прокси ниже:

template <class F> 
void proxy(F func) { 
    typedef function_traits<decltype(func)> traits; 
    typename traits::result_type r; 
    traits::arg<0>::type p;       // compile error 
} 

Я получаю ошибку компиляции ниже:

error: `::type` has not been declared 
error: expected `;` before `p` 

Почему возвращаемый тип может быть скомпилирован, пока тип параметра не может, как я могу заставить его работать?

ответ

9

Использование TypeName и шаблонов:

typename traits::template arg<0>::type p;  

Одна линия объяснения:

  • Почему typename? Потому что ::type является зависимым типом.
  • Почему template? Потому что arg<> является зависимым шаблоном.

Надеюсь, что это поможет.

+1

+1: выдающаяся диатриба об использовании 'template' и' typename' [находится здесь] (http://stackoverflow.com/questions/610245/where-and-why-do-i-have- к пут-на-шаблон-и-TypeName-ключевые слова). – WhozCraig

+0

@Nawaz Что делать, если p является типом 'reference'? – xunzhang

+0

@xunzhang: Я не понимал, о чем вы спрашиваете. Позвольте мне объяснить: 'p' - это переменная, а не тип, ее тип -' typename traits :: template arg <0> :: type', который может быть ссылкой. Так в чем ваш вопрос? – Nawaz