san*_*rey 9 c++ lambda templates functional-programming c++14
我需要一种方法来计算函数的参数类型,所以我编写了一个closure_traits类,如下所示,受到启发是否有可能找出lambda的参数类型和返回类型?.
但是,当我尝试将它应用于一个简单的lambda时,我得到'operator()'不是'(lambda type)'的成员的错误.但是,根据cppreference,lambda确实有一个operator().我也尝试过使用std :: function,并得到了相同的错误.我想我不确定出了什么问题,任何帮助都会非常感激.
#include<type_traits>
#include<tuple>
#include<utility>
#include<iostream>
/* For generic types use the type signature of their operator() */
template <typename T>
struct closure_traits : public
closure_traits<decltype(&T::operator())> {};
/* Otherwise, we do a template match on a function type. */
template <typename ClassType, typename ReturnType,
typename... ArgTypes>
struct closure_traits<ReturnType (ClassType::*) (ArgTypes... args)>
{
using arity = std::integral_constant<std::size_t,
sizeof...(ArgTypes)>;
using Ret = ReturnType;
/* The argument types will be the same as the types of the
* elements of a tuple composed of them.
*/
template <std::size_t I>
struct Args {
using type = typename std::tuple_element<I,
std::tuple<ArgTypes...>>::type;
};
};
int main() {
auto thing = [=] (int x) {return x;};
std::cerr << "The number of arguments is "
<< closure_traits<decltype(thing)>::arity << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到的编译器错误消息如下.我的编译命令只是g ++ -std = c ++ 14 main.cpp.
main.cpp: In instantiation of ‘struct closure_traits<int (main()::<lambda(int)>::*)(int) const>’:
main.cpp:9:8: required from ‘struct closure_traits<main()::<lambda(int)> >’
main.cpp:34:82: required from here
main.cpp:9:56: error: ‘operator()’ is not a member of ‘int (main()::<lambda(int)>::*)(int) const’
struct closure_traits : public closure_traits<decltype(&T::operator())> {};
^
main.cpp: In function ‘int main()’:
main.cpp:34:51: error: ‘arity’ is not a member of ‘closure_traits<main()::<lambda(int)> >’
std::cerr << "The number of arguments is " << closure_traits<decltype(thing)>::arity << std::endl;
Run Code Online (Sandbox Code Playgroud)
您的专业化与decltype(&T::operator())参数不符.
因此,编译器不是选择专门化(如您所愿),而是强制以递归方式选择相同的主模板.这使得它&T::operator()在已经应用一次之后再次应用表达式.即初始尝试&T::operator()实际上成功,但编译器尝试&T::operator()再次应用,何时T已经int (main()::<lambda(int)>::*)(int) const.显然,后者没有operator (),这就是你收到此错误消息的原因.
const模板参数声明中缺少无法选择专业化的原因.lambda operator ()实际上是constlambda类的成员.添加const到您的专业化声明
template <typename ClassType, typename ReturnType,
typename... ArgTypes>
struct closure_traits<ReturnType (ClassType::*) (ArgTypes... args) const>
...
Run Code Online (Sandbox Code Playgroud)
编译器将遵循您希望它遵循的特化路径.
而且,当然,你必须打印closure_traits<decltype(thing)>::arity::value,而不仅仅是closure_traits<decltype(thing)>::arity.
| 归档时间: |
|
| 查看次数: |
666 次 |
| 最近记录: |