我如何传递变量到一个函数,与任何签名,使用模板
How do I pass variables into a function, with any signature, using templates?
我的问题如下。我想在包装器中调用任何自由函数,并且我想在包装器中自动传递参数。
的想法是通过函数调用传递参数,如GetArgument<float>()
。最后,我想从虚拟机获取这些值,并将它们传递给我要绑定的函数。我需要将具有正确类型的正确GetArgument<T>
放置在函数调用中的正确位置。
这是我尝试的一个最小的工作示例。主要:
#include "FunctionWrapper.h"
#include <iostream>
void say( int val ) {
std::cout << "called with " << val << std::endl;
}
int main() {
InvokeWithArguments( say );
return 0;
}
这就是奇迹发生的地方。在源代码的末尾,我得到一个编译器错误:
#pragma once
#include <cstdlib>
#include <cstdint>
#include <tuple>
#include <type_traits>
/*
* FUNCTION TRAITS
*/
template< typename F >
struct FunctionTraits;
template< typename R, typename... Args >
struct FunctionTraits< R( Args... ) > {
using ReturnType = R;
constexpr static const uint32_t arity = sizeof...( Args );
template< std::size_t N >
struct Argument {
static_assert( N < arity, "FunctionTraits error: invalid argument count parameter" );
using type = typename std::tuple_element< N, std::tuple< Args... > >::type;
};
};
/*
* ARGUMENT GETTER (for demonstration)
**/
template< typename T >
T GetArgument() {}
template<>
float GetArgument() {
return 3.3f;
}
template<>
int GetArgument() {
return 5;
}
/*
* AUTOMATIC INVOCATION
**/
template< typename Function, std::size_t... index >
decltype( auto ) InvokeHelper( Function&& f, std::index_sequence<index...> ) {
using Traits = FunctionTraits< decltype(f) >;
// COMPILER FAILS HERE, EXPECTS ) BEFORE :: TOKEN
return f( GetArgument< Traits::Argument<index>::type >()... );
}
template< typename Function >
decltype( auto ) InvokeWithArguments( Function&& f ) {
constexpr auto Arity = FunctionTraits< decltype(f) >::arity;
return InvokeHelper( std::forward<Function>( f ), std::make_index_sequence<Arity>{} );
}
我不明白为什么return f( GetArgument< Traits::Argument<index>::type >()... );
失败了。据我所知,Traits::Argument<index>::type
是一种类型,所以我不知道为什么编译器会期望在它中间关闭函数调用。
最后,一个小的完整性检查,因为我是这样一个模板编程新手。我希望在函数调用的括号之间有一个逗号分隔的GetArgument<T>
调用列表。我的代码就是这么做的吗?
你应该使用:
return f( GetArgument< typename Traits::template Argument<index>::type >()... );
// ^^^^^^^^ ^^^^^^^^^
在此之后,编译器会抱怨你的FunctionTraits<void(&)(int)>
不能被实例化,这可以通过通过std::remove_reference
删除函数类型中的引用来修复。
这是由于void(int)
不同于void(&)(int)
, void(*)(int)
不同造成的。前者是函数类型,后者是函数引用类型,后者是函数指针类型。
所有这些将产生:
template< typename Function, std::size_t... index >
decltype( auto ) InvokeHelper( Function&& f, std::index_sequence<index...> ) {
using Traits = FunctionTraits< typename std::remove_reference<decltype(f)>::type >;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^
return f( GetArgument< typename Traits::template Argument<index>::type >()... );
// ^^^^^^^^ ^^^^^^^^^
}
template< typename Function >
decltype( auto ) InvokeWithArguments( Function&& f ) {
constexpr auto Arity = FunctionTraits< typename std::remove_reference<decltype(f)>::type >::arity;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^
return InvokeHelper( std::forward<Function>( f ), std::make_index_sequence<Arity>{} );
}
现场演示
相关文章:
- 是否有任何 C 标准函数将值"1"传递给所有 (%s)
- 在将匿名对象作为参数传递时,不会调用任何构造函数
- 任何 GraphAttributes 函数调用上的 OGDF 段错误
- 试图在具有std ::任何构造函数的基类中调用复制构造函数的问题
- 类 'MainWindow' 中未声明任何成员函数
- 是否有任何窗口函数可以使用域名获取所有OU(组织单位)名称
- 编译时类中未声明任何成员函数时出错
- QMainWindow从main()函数打开,但不从任何其他函数打开
- 任何时间函数保证为调用返回不同的值
- 提升::任何构造函数 - 常量类型重载分辨率
- 是否有任何 pthread 函数可以在最后一个线程终止时调用某些内容
- 使用 "interface" 时在类中未声明任何成员函数
- 任何表示函数参数的方式
- 无需任何库函数即可将浮点数转换为字符串的有效方法
- 函数指向具有任意数量参数的任何成员函数
- 如何在不使用任何基本函数的情况下拆分字符数组
- 包装任何API函数
- main()或任何其他函数之外的Malloc(即在全局范围内)
- 在c++ 11中,当类没有任何构造函数时,自动生成类成员函数
- 点击按钮 -> 执行我在参数中给出的任何类函数 (C++)