从这个问题开始(是否可以找出lambda的参数类型和返回类型?)我使用function_traits了很多建议.然而,随着C++ 14的多态性lambda已经到来,他们给了我一个艰难的时间.
template <typename T>
struct function_traits
: public function_traits<decltype(&T::operator())>
{};
// For generic types, directly use the result of the signature of its 'operator()'
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const>
// we specialize for pointers to member function
{
enum { arity = sizeof...(Args) };
// arity is the number of arguments.
typedef ReturnType result_type;
template <size_t i>
struct arg
{
typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
// the i-th argument is …Run Code Online (Sandbox Code Playgroud) 我创建了一个模板类,其中包含std::function一个成员,方法如下:
template<typename Ret, typename... Args>
class Foo
{
private:
std::function<Ret(Args...)> _func;
public:
Foo(const std::function<Ret(Args...)>& func):
_func(func)
{}
};
Run Code Online (Sandbox Code Playgroud)
为了不必指定传递函数的参数和返回类型,我创建了一些make_foo重载:
template<typename Ret, typename... Args>
auto make_foo(Ret (&func)(Args...))
-> Foo<Ret, Args...>
{
return { std::function<Ret(Args...)>(func) };
}
template<typename Ret, typename... Args>
auto make_foo(const std::function<Ret(Args...)>& func)
-> Foo<Ret, Args...>
{
return { func };
}
Run Code Online (Sandbox Code Playgroud)
但是,我无法创建一个make_foo以lambda作为参数的重载:
template<typename Ret, typename... Args>
auto make_foo(??? func)
-> Foo<Ret, Args...>
{
return { std::function<Ret(Args...)>(func) };
}
Run Code Online (Sandbox Code Playgroud)
我只是找不到从lambda自动推导出返回类型和参数类型的方法.有没有一种解决这种问题的惯用方法?
我有以下代码片段,我struct quick用模板化static方法定义random了一些特殊化:
(我使用function_traits其他SO答案.附在底部供参考.)
struct quick
{
template <typename T>
static T random();
template <typename F>
static void check(F f)
{
constexpr auto arity = function_traits<F>::arity; // easy :)
std::cout << arity << std::endl;
typedef typename function_traits<F>::template arg<0>::type type0; // easy:)
// how to get all types of all F's parameters?
}
};
template <>
std::string quick::random<std::string>()
{
return std::string("test");
}
template <>
int quick::random<int>()
{
return 1;
}
Run Code Online (Sandbox Code Playgroud)
我想获取所有类型F的参数,check …
我想包装一个boost::function类成员,以便它可以通过以下方式使用:
using namespace boost;
using namespace boost::python;
struct gui_button_t
{
function<void()> on_pressed;
};
class_<gui_button_t>("GuiButton", init<>())
.def("on_pressed", &gui_button_t::on_pressed);
Run Code Online (Sandbox Code Playgroud)
然后在Python中:
def callback_function():
print 'button has been pressed'
button = GuiButton()
button.on_pressed = callback_function
button.on_pressed() # function should be callable from C++ or Python
Run Code Online (Sandbox Code Playgroud)
但是,尝试此操作会产生关于类模板参数等的大量错误.
我做了一些搜索,但一直找不到我一直在寻找的答案.下面的文章有点接近,但他们没有直接涉及这个主题.
http://bfroehle.com/2011/07/18/boost-python-and-boost-function-ii/
我在这做错了什么?为获得此功能所需的界面,我需要做什么?
提前谢谢了.
我有一个从另一个.hpp文件导入的函数指针类型.就像是:
typedef void (*PFN_func)(int i);
Run Code Online (Sandbox Code Playgroud)
我想创建一个相同类型的仿函数:
std::function<PFN_func>
Run Code Online (Sandbox Code Playgroud)
但这不起作用.我不想要像这样的解决方案
std::function<void(int)>
Run Code Online (Sandbox Code Playgroud)
因为mt函数指针定义要复杂得多
在这个问题中,这似乎可以解决lambda的情况.但那个是2011年的答案,我正在寻找一个普遍的案例:lambdas,常规函数和函子.并且,如果可能的话,通过最现代的c ++语言添加.(注意:) g++ -std=c++1y test.cpp.
所以,给定一个函数(或一个lambda),我试图找出它的返回类型是什么.例如,声明一个变量(简化的情况).
using namespace std;
template<typename F>
void test (F h) {
// any of the following should be equivalent to int a; int b; int c;
decltype(h) a; // <<<<< wrong
result_of(h) b; // <<<<<< wrong
result_of<decltype(h)> c; // <<<<<< wrong
}
int a_function (int i) {
return 2*i;
}
int main () {
test (a_function);
}
Run Code Online (Sandbox Code Playgroud)
谢谢.
免责声明:我已经看到了这个问题,而且我正在问decltype,在接受的答案中建议如何使用它.
基本上我尝试(有点乐趣,为了方便而有点用于学习目的)来实现标准算法的小包装器,这简化了它们在应用于整个容器时的使用.其主要思想是,以摆脱.begin()和.end()仅仅指定必须在其上应用的算法的容器.
然后,我想知道从标准算法返回类型本身推断我的包装器的返回类型是否可能(顺便说一下并不愚蠢).
目前,我尝试了以下(对于std :: count):
template<class Cnt,
class T>
inline
auto count(Cnt _cnt, const T& _val) -> decltype(std::count){}
Run Code Online (Sandbox Code Playgroud)
但它在编译时给了我一个错误:
无法专门化功能模板''unknown-type'ragut :: count(Cnt,const T&)'
我认为这可能还不够decltype(std::count),并且假设它要求更具体的参数:
decltype(std::count<std::iterator<std::input_iterator_tag,Cnt::value_type> >)
Run Code Online (Sandbox Code Playgroud)
但这也给出了同样的错误.
我想知道它是否真的不是愚蠢而且可能做到这一点.
我遇到了一些类似的问题并找到了这个问题:是否有可能找出lambda的参数类型和返回类型?.
我在这个问题的答案中使用代码:
#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;
};
};
Run Code Online (Sandbox Code Playgroud)
在我的例子中,(lambda)函数是用户定义的,所以我必须使用模板函数来根据用户定义的函数做一些事情,所以我在下面添加一个代理函数:
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
}
Run Code Online (Sandbox Code Playgroud)
我得到以下编译错误:
error: `::type` has not been declared
error: expected `;` …Run Code Online (Sandbox Code Playgroud) 我想编写一个'评估'函数,它接受一个带有整数的未指定返回类型的函数作为输入,并使用一个整数来调用该函数.
我想出的是以下内容:
#include <functional>
template<typename T>
T eval(function<T(int)> f, int x) {
return f(x);
}
Run Code Online (Sandbox Code Playgroud)
假设我有一个auto func = [] (int x) -> long { return (long)x * x; }我想用上面的函数评估的东西.之前我使用模板函数的方式是简单地调用它,就像我任何其他函数一样,让编译器推断出类型.
但是,这不适用于此eval功能.eval<long>(func, 5)编译并正常工作,但eval(func, 5)不会:
Aufgaben10.5.cpp:23:25: error: no matching function for call to 'eval(main()::__lambda0&, int)'
cout << eval(func, 5) << endl;
^
Aufgaben10.5.cpp:23:25: note: candidate is:
Aufgaben10.5.cpp:8:3: note: template<class T> T eval(std::function<T(int)>, int)
T eval(function<T(int)> f, int x) {
^
Aufgaben10.5.cpp:8:3: note: template argument deduction/substitution …Run Code Online (Sandbox Code Playgroud) 我试图理解这段代码,并且我发现了一些关于这个主题的更多内容。
以紧凑的形式:
#include <tuple>
namespace sqlite {
namespace utility {
template<typename> struct function_traits;
template <typename Function>
struct function_traits : public function_traits<
decltype(&Function::operator())
> { };
template <
typename ClassType,
typename ReturnType,
typename... Arguments
>
struct function_traits<
ReturnType(ClassType::*)(Arguments...) const
> {
typedef ReturnType result_type;
template <std::size_t Index>
using argument = typename std::tuple_element<
Index,
std::tuple<Arguments...>
>::type;
static const std::size_t arity = sizeof...(Arguments);
};
}
}
Run Code Online (Sandbox Code Playgroud)
这使我了解了该语言的指向成员函数的指针特性,并且此时我非常清楚如何使用函数特征(相当简单,我不仅可以提取返回类型,还可以提取数量,甚至参数的类型),但我一直在理解为什么它有效,或者为什么它甚至可能有效......
如果lambda(或函数对象)有默认参数,在编译时告诉最简单的方法是什么?例:
auto f = [](int i=0){};
auto g = [](int i){};
static_assert(has_default_arg<decltype(f)>::value==true);
static_assert(has_default_arg<decltype(g)>::value==false);
Run Code Online (Sandbox Code Playgroud)