基于模板形参成员函数实参的模板特化
Template specialization based on arguments of template parameter member function
我可以 运行 此代码,但是当我启用 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() 的模板参数。
有人知道如何使这个例子起作用吗?
我需要它 select a class,这里是 doStuff,基于模板参数 operator() 是否接受参数,在另一个模板化的 class 里面,这里是 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;
}
感谢所有模板书呆子的帮助:)
在你的 struct Bla
中你应该说 DoStuff<Type> doStuff;
(这里不需要也不允许使用 typename)。
在(修正版)中:
template <typename Functor, typename Arg = typename first_argument<Functor>::type>
struct DoStuff;
您在 first_argument<Functor>::type
之前错过了 typename
。
我可以 运行 此代码,但是当我启用 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() 的模板参数。 有人知道如何使这个例子起作用吗? 我需要它 select a class,这里是 doStuff,基于模板参数 operator() 是否接受参数,在另一个模板化的 class 里面,这里是 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;
}
感谢所有模板书呆子的帮助:)
在你的 struct Bla
中你应该说 DoStuff<Type> doStuff;
(这里不需要也不允许使用 typename)。
在(修正版)中:
template <typename Functor, typename Arg = typename first_argument<Functor>::type>
struct DoStuff;
您在 first_argument<Functor>::type
之前错过了 typename
。