2016-05-23 249 views
0

當我使3出注釋行不編譯了,我可以但是運行此代碼,並提供了以下錯誤:模板專業化

1>d:\git\testprojekt\testprojekt\testprojekt.cpp(41): warning C4346: 'first_argument<F>::type': dependent name is not a type 
1> d:\git\testprojekt\testprojekt\testprojekt.cpp(41): note: prefix with 'typename' to indicate a type 
1> d:\git\testprojekt\testprojekt\testprojekt.cpp(43): note: see reference to class template instantiation 'Bla<Type>' being compiled 
1>d:\git\testprojekt\testprojekt\testprojekt.cpp(41): error C2923: 'DoStuff': 'first_argument<F>::type' is not a valid template type argument for parameter 'Arg' 
1> d:\git\testprojekt\testprojekt\testprojekt.cpp(22): note: see declaration of 'first_argument<F>::type' 

我知道爲什麼它的工作原理在於編譯器想要確保Bla爲各種模板參數編譯,但first_argument只能處理具有operator()定義的模板參數。 有沒有人知道如何使這個例子工作? 我需要它來選擇一個類,這裏​​doStuff,基於模板參數operator()是否接受一個參數,在另一個模板類,在這裏Bla。

#include <iostream> 


template<typename F, typename Ret> 
void helper(Ret(F::*)()); 

template<typename F, typename Ret> 
void helper(Ret(F::*)() const); 


template<typename F, typename Ret, typename A, typename... Rest> 
char helper(Ret(F::*)(A, Rest...)); 

template<typename F, typename Ret, typename A, typename... Rest> 
char helper(Ret(F::*)(A, Rest...) const); 

template<typename F> 
struct first_argument { 
    typedef decltype(helper(&F::operator())) type; 
}; 

template <typename Functor, typename Arg = first_argument<Functor>::type> 
struct DoStuff; 

template <typename Functor> 
struct DoStuff<Functor, char> 
{ 
    void print() { std::cout << "has arg" << std::endl; }; 
}; 

template <typename Functor> 
struct DoStuff<Functor, void> 
{ 
    void print() { std::cout << "does not have arg" << std::endl; }; 
}; 


template <typename Type> 
struct Bla 
{ 
    //DoStuff<typename Type> doStuff; 
    //void print() { doStuff.print(); }; 
}; 



int main() 
{ 
    struct functorNoArg { 
     void operator()() {}; 
    }; 

    struct functorArg { 
     void operator()(int a) { std::cout << a; }; 
    }; 

    auto lambdaNoArg = []() {}; 
    auto lambdaArg = [](int a) {}; 


    std::cout << std::is_same<first_argument<functorArg>::type,int>::value <<std::endl; // this works 

    DoStuff<functorArg> doStuff; 
    doStuff.print(); 

    DoStuff<functorNoArg> doStuff2; 
    doStuff2.print(); 

    DoStuff<decltype(lambdaArg)> doStuff3; 
    doStuff3.print(); 

    DoStuff<decltype(lambdaNoArg)> doStuff4; 
    doStuff4.print(); 

    Bla<functorArg> bla; 
    //bla.print(); 

    return 0; 
} 

感謝所有模板書呆子幫助:)

+1

你不把'typename'放在你想要的地方,而你把'typename'放在你不應該在的地方 –

+1

當編譯器說你缺少'typename'時,它並不意味着'DoStuff doStuff ;',這意味着'typename Arg = typename first_argument :: type' –

回答

1

在你struct Bla你應該說(無需或這裏不允許類型名稱)DoStuff<Type> doStuff;

在(修正版):

template <typename Functor, typename Arg = typename first_argument<Functor>::type> struct DoStuff;

你失蹤typenamefirst_argument<Functor>::type之前。

+0

啊謝謝,是的,一個typename只是一些愚蠢的東西,我試圖做工後,它最初沒有工作:P – bodzcount