我正在尝试存储std::tuple不同数量的值,这些值稍后将用作调用与存储类型匹配的函数指针的参数.
我创建了一个简化的示例,显示了我正在努力解决的问题:
#include <iostream>
#include <tuple>
void f(int a, double b, void* c) {
std::cout << a << ":" << b << ":" << c << std::endl;
}
template <typename ...Args>
struct save_it_for_later {
std::tuple<Args...> params;
void (*func)(Args...);
void delayed_dispatch() {
// How can I "unpack" params to call func?
func(std::get<0>(params), std::get<1>(params), std::get<2>(params));
// But I *really* don't want to write 20 versions of dispatch so I'd rather
// write something like:
func(params...); // Not legal
}
}; …Run Code Online (Sandbox Code Playgroud) c++ function-pointers variadic-templates c++11 iterable-unpacking
能够在C++编译时创建和操作字符串有几个有用的应用程序.尽管可以在C++中创建编译时字符串,但是该过程非常麻烦,因为字符串需要声明为可变字符序列,例如
using str = sequence<'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!'>;
Run Code Online (Sandbox Code Playgroud)
诸如字符串连接,子字符串提取等许多操作可以很容易地实现为对字符序列的操作.是否可以更方便地声明编译时字符串?如果没有,是否有一个提案可以方便地声明编译时字符串?
理想情况下,我们希望能够如下声明编译时字符串:
// Approach 1
using str1 = sequence<"Hello, world!">;
Run Code Online (Sandbox Code Playgroud)
或者,使用用户定义的文字,
// Approach 2
constexpr auto str2 = "Hello, world!"_s;
Run Code Online (Sandbox Code Playgroud)
哪里decltype(str2)有一个constexpr构造函数.方法1的混乱版本可以实现,利用您可以执行以下操作的事实:
template <unsigned Size, const char Array[Size]>
struct foo;
Run Code Online (Sandbox Code Playgroud)
但是,数组需要有外部链接,所以要使方法1起作用,我们必须编写如下内容:
/* Implementation of array to sequence goes here. */
constexpr const char str[] = "Hello, world!";
int main()
{
using s = string<13, str>;
return 0; …Run Code Online (Sandbox Code Playgroud) 这是我之前关于漂亮印刷STL容器的问题的后续行动,为此我们设法开发了一个非常优雅且完全通用的解决方案.
在下一步中,我想std::tuple<Args...>使用可变参数模板包含漂亮打印(因此这是严格的C++ 11).因为std::pair<S,T>,我只是说
std::ostream & operator<<(std::ostream & o, const std::pair<S,T> & p)
{
return o << "(" << p.first << ", " << p.second << ")";
}
Run Code Online (Sandbox Code Playgroud)
打印元组的类似结构是什么?
我已经尝试了各种模板参数堆栈解包,传递索引并使用SFINAE来发现我何时处于最后一个元素,但没有成功.我不会用破碎的代码给你带来负担; 问题描述有希望直截了当.基本上,我想要以下行为:
auto a = std::make_tuple(5, "Hello", -0.1);
std::cout << a << std::endl; // prints: (5, "Hello", -0.1)
Run Code Online (Sandbox Code Playgroud)
与前一个问题包含相同级别的通用性(char/wchar_t,pair delimiters)的加分点!
在C++ 11模板中,有没有办法将元组用作(可能是模板)函数的各个args?
示例:
假设我有此功能:
void foo(int a, int b)
{
}
Run Code Online (Sandbox Code Playgroud)
我有元组auto bar = std::make_tuple(1, 2).
我可以用它以foo(1, 2)一种模板的方式打电话吗?
我的意思并不简单,foo(std::get<0>(bar), std::get<1>(bar))因为我想在一个不知道args数量的模板中这样做.
更完整的例子:
template<typename Func, typename... Args>
void caller(Func func, Args... args)
{
auto argtuple = std::make_tuple(args...);
do_stuff_with_tuple(argtuple);
func(insert_magic_here(argtuple)); // <-- this is the hard part
}
Run Code Online (Sandbox Code Playgroud)
我应该注意,我宁愿不创建一个适用于一个arg的模板,另一个适用于两个arg的模板等等...
目标:
我想在不相关的类型上实现类型安全的动态多态(即函数调用的运行时调度)- 即在没有公共基类的类型上.在我看来,这是可以实现的,或者至少在理论上是合理的.我会尝试更正式地定义我的问题.
问题定义:
鉴于以下内容:
A1, ..., An,每个类型都有一个被调用的方法f,可能具有不同的签名,但具有相同的返回类型 R ; 和boost::variant<A1*, ..., An*>对象v(或任何其他类型的变体),它可以并且必须在任何时候假设任何这些类型的一个值;我的目标是写指令概念上等同于v.f(arg_1, ..., arg_m);将获得在运行时调度的功能Ai::f,如果实际类型包含的价值v是Ai.如果调用参数与每个函数的形式参数不兼容Ai,编译器应该引发错误.
当然我不需要坚持语法v.f(arg_1, ..., arg_m):例如,类似的东西call(v, f, ...)也是可以接受的.
我试图在C++中实现这一点,但到目前为止我还没有找到一个好的解决方案(我确实有很多坏的解决方案).下面我通过"好的解决方案"澄清我的意思.
约束:
一个好的解决方案是让我模仿v.f(...)成语的任何东西,例如call_on_variant(v, f, ...);,并满足以下约束:
f …有没有办法去除一个std::tuple<T...>以便让它回来T...?
例
假设vct<T...>是一个预先存在的 可变参数类模板,
using U = std::tuple<int,char,std::string>;
using X = vct<int,char,std::string>;
using Y = vct< strip<U> >; // should be same as X
Run Code Online (Sandbox Code Playgroud)
笔记
我知道std :: tuple_element,但我需要所有元素,以一种可用的形式T...
作为参考,我发现这个问题,这是类似的,但我的需求是较为简单(所以我希望有一个简单的解决方案):我需要的是那些在类型列表tuple-我不关心tuple实例的实际值.
我正在编写一个通用函数包装器,它可以将任何函数包装到具有该形式的lua样式调用中
int lua_function(lua_State*L)
我希望包装函数是即时生成的,所以我想将函数作为模板参数传递.如果你知道参数的数量(例如2),这是微不足道的:
template <typename R, typename Arg1, typename Arg2, R F(Arg1, Args)>
struct wrapper
Run Code Online (Sandbox Code Playgroud)
但是,我不知道这个数字,所以我请求variadic模板参数求助
// This won't work
template <typename R, typename... Args, R F(Args...)>
struct wrapper
Run Code Online (Sandbox Code Playgroud)
上面的内容不会编译,因为variadic参数必须是最后一个.所以我使用两个级别的模板,外部模板捕获类型,内部模板捕获函数:
template <typename R, typename... Args>
struct func_type<R(Args...)>
{
// Inner function wrapper take the function pointer as a template argument
template <R F(Args...)>
struct func
{
static int call( lua_State *L )
{
// extract arguments from L
F(/*arguments*/);
return 1;
}
};
};
Run Code Online (Sandbox Code Playgroud)
这是有效的,除了包装像这样的函数
double sin(double d) {} …Run Code Online (Sandbox Code Playgroud) 我使用C++编写代码并对省略号有一些问题:
是否可以将类或类指针传入省略号?
基本上我想要做的是传递char*和的类型中的可变数量的参数class.我目前正在使用省略号并试图弄清楚如何传入课堂.如果省略号不适用于此处,有哪些选项?
我想让用户直接调用函数,func( params 1, params2, ...)而不是在将向量或数组作为参数传递给函数之前先将params分配给向量或数组.
以下程序在带有-O3的centos上的gcc 4.6.2下编译:
#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>
using namespace std;
template <typename T>
class F {
public:
typedef void (T::*Func)();
F(Func f) : f_(f) {}
void operator()(T& t) {
(t.*f_)();
}
private:
Func f_;
};
struct X {
X() : x_(0) {}
void f(){
++x_;
}
int x_;
};
int main()
{
const int N = 100000000;
vector<X> xv(N);
auto begin = clock();
for_each (xv.begin(), xv.end(), F<X>(&X::f));
auto end = clock();
cout << end - begin << …Run Code Online (Sandbox Code Playgroud) 假设我有一个std::tuple:
std::tuple<Types...> myTuple;
// fill myTuple with stuff
Run Code Online (Sandbox Code Playgroud)
现在我想找到是否func为lambda中的任何元素返回true,其中func有一些lambda,例如:
auto func = [](auto&& x) -> bool { return someOperation(x); }
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?请注意,这Types...可能很大,所以我不想每次迭代所有元素.