卡在TR1中,对于测试程序,我需要对特定类型的多个对象执行某些操作.我有几个元组类型定义,如下所示:
typedef std::tr1::tuple< bool
, signed char
, signed short
, signed int
, signed long long
, unsigned char
, unsigned short
, unsigned int
, unsigned long long > integral_types;
Run Code Online (Sandbox Code Playgroud)
从每个元组类型创建一个对象.然后我有类似这样的功能模板:
template<typename T>
void invoke_operation_1(T& obj);
Run Code Online (Sandbox Code Playgroud)
需要为元组对象中的所有对象调用它们.
我如何在C++ 03中做到这一点?
我正在尝试练习一些模板编程.也许有一种标准的方法可以做到这一点,我会感谢这些答案,但我的主要目标是练习模板编程技术,所以我试着自己实现它:
我需要连接多个元组,但作为类型,不像std::cat_tuple它.所以,我需要这样的东西cat<std::tuple<int, float>, std::tuple<char, bool>, ...>来获得std::tuple<int, float, char, bool, ...>的类型.
我当前的尝试失败并出现is not a template错误:
/* Concat tuples as types: */
template <typename first_t, typename... rest_t> struct cat {
using type = typename _cat<first_t, typename cat<rest_t...>::type>::type;
^^^^ cat is not a template
};
template <typename first_t, typename second_t>
struct cat<first_t, second_t> {
using type = typename _cat<first_t, second_t>::type;
^^^^ cat is not a template
};
// Concat two tuples:
template <typename, typename> struct …Run Code Online (Sandbox Code Playgroud) c++ template-meta-programming variadic-templates c++11 stdtuple
假设我有一个模板,它由类类型和许多参数类型进行参数化.匹配这些类型的一组参数存储在元组中.如何将这些传递给类类型的构造函数?
在几乎C++ 11代码中:
template<typename T, typename... Args>
struct foo {
tuple<Args...> args;
T gen() { return T(get<0>(args), get<1>(args), ...); }
};
Run Code Online (Sandbox Code Playgroud)
如何...在不修复长度的情况下填充构造函数调用?
我想我可以想出一些复杂的递归模板调用机制来做到这一点,但是我不敢相信我是第一个想要这个的人,所以我想这里会有现成的解决方案. ,甚至可能在标准库中.
我有一个函数traits结构,它使用std::tuple_element以下方法提供函数参数的类型:
#include <iostream>
#include <tuple>
#include <typeinfo>
template <typename T>
struct function_traits;
template <typename T_Ret, typename ...T_Args>
struct function_traits<T_Ret(T_Args...)> {
// Number of arguments.
enum { arity = sizeof...(T_Args) };
// Argument types.
template <size_t i>
struct args {
using type
= typename std::tuple_element<i, std::tuple<T_Args...>>::type;
};
};
int main() {
using Arg0 = function_traits<int(float)>::args<0>::type;
//using Arg1 = function_traits<int(float)>::args<1>::type; // Error, should be void.
std::cout << typeid(Arg0).name() << std::endl;
//std::cout << typeid(Arg1).name() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
如果索引i超出范围( …
struct Y { };
struct X : std::tuple<Y> { };
int main()
{
std::get<0>(std::make_tuple(X{}));
}
Run Code Online (Sandbox Code Playgroud)
clang++当使用libc ++时,上面的代码编译并按预期工作.
上面的代码失败,都编译clang++和g++使用时的libstdc ++,错误如下:
include/c++/7.0.1/tuple:1302:36:
error: no matching function for call to ‘__get_helper<0>(std::tuple<X>&)’
{ return std::__get_helper<__i>(__t); }
~~~~~~~~~~~~~~~~~~~~~~^~~~~
include/c++/7.0.1/tuple:1290:5:
note: candidate: template<long unsigned int __i, class _Head, class ... _Tail>
constexpr _Head& std::__get_helper(std::_Tuple_impl<_Idx, _Head, _Tail ...>&)
__get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
^~~~~~~~~~~~
include/c++/7.0.1/tuple:1290:5:
note: template argument deduction/substitution failed:
include/c++/7.0.1/tuple:1302:36:
note: ‘std::_Tuple_impl<0, _Head, _Tail ...>’ is …Run Code Online (Sandbox Code Playgroud) 我想编写一个fold函数std::tuple来计算例如给定元组中所有元素的总和(或乘积).例如,给定
std::tuple<int,double> t = std::make_tuple(1,2);
Run Code Online (Sandbox Code Playgroud)
我想算一下
auto s = sumT(t); //giving 3
Run Code Online (Sandbox Code Playgroud)
我试过但是无法在下面编译我的模板编程(c ++ 11/1z)代码.我也试着去适应接受的答案对我的其他问题(如何执行用C元组算术++(C++ 11/C++ 17)? ),但无法弄清楚如何使用std::index_sequence在这种情况下.
我遇到的问题是:
1)我无法弄清楚类型,例如如何使用第一个元素的类型作为返回类型.目前,我_res在模板中使用了一个类型,但我不知道是否会阻止c ++的自动类型推理.
2)我想在不使用显式初始元素的情况下对其进行编程0,以便可以将其用于其他类型的fold操作.
目前,递归在最后一个元素处结束.我想结束递归,_size - 1以便我可以直接对最后一个元素执行操作而不需要求助0.
我下面的代码试图通过递归来做到这一点.但我不熟悉模板编程,以及循环如何为元组工作.
有人可以帮助修复代码或提出更好的解决方案吗?
到目前为止我的代码是:
#include <tuple>
#include <iostream>
#include <functional>
// helper class for fold operations
template<typename Op,typename _res, typename _Tp, size_t _i, size_t _size>
struct _tuple_fold {
static constexpr _res _op(Op const & op, const _Tp& _t) { …Run Code Online (Sandbox Code Playgroud) C ++ 17引入了结构化绑定声明:auto [a, b] = some_tuple;。
这对于像std :: tuple这样的东西都是开箱即用的。也可以使其适用于自定义类型,您只需(除其他外)提供一个get-function模板即可,作为成员或在自定义类之外。
对于标准类,这是通过非成员get放置在std-namespace中来完成的:auto a = std::get<0>(some_tuple);works,但不是auto a = some_tuple.get<0>();。
但这对我来说很奇怪:由于我们必须为get显式指定模板参数N,因此ADL不起作用,例如,我们不能只写auto a = get<0>(some_tuple);。但是,使用元组的结构化绑定声明也不应工作,因为它只是诸如get<N>(some_tuple)or或some_tuple.get<N>()(modulo some &)之类的调用的语法糖!确实,当我在命名空间内仅为我的自定义类提供get的非成员版本时,它将无法正常工作! 编辑:自定义类的结构化绑定也可以正常工作,请参见已接受答案中的代码片段,以获取一个最小示例!
那么,该标准的实现者如何在没有get成员的情况下使结构化绑定适用于元组,以及如何为我的自定义类实现相同的行为?
代码如下
#include <tuple>
int main()
{
auto [a] = std::make_tuple(1);
return [a]() -> int { return a; }();
}
Run Code Online (Sandbox Code Playgroud)
在 clang 12 中产生错误:
<source>:6:13: error: 'a' in capture list does not name a variable
return [a]() -> int { return a; }();
<source>:6:34: error: reference to local binding 'a' declared in enclosing function 'main'
return [a]() -> int { return a; }();
Run Code Online (Sandbox Code Playgroud)
然而,Visual Studio 2019 和 gcc 11 都-std=c++20 -Wall -Wextra -pedantic-errors接受它。https://gcc.godbolt.org/z/jbjsnfWfj
所以它们仍然违反了结构化绑定永远不是变量名称的规则,使它们永远无法捕获?
我有一个函数f(),它返回std::pair<A, B>具有某些类型A和B. 我还有另一个函数g(),它调用f()两次并返回一个std::tuple<A, B, A, B>. 有没有办法tuple直接从两个调用构造返回f()?所以我想将当前代码的最后三行作为快捷方式:
std::tuple<A, B, A, B>
g(type1 arg1, type2 arg2, ...) {
// perform some preprocessing
auto pair1 = f(...);
auto pair2 = f(...);
return { pair1.first, pair1.second, pair2.first, pair2.second }
}
Run Code Online (Sandbox Code Playgroud)
成一个班轮(而不是三个)。如果该解决方案也适用于任意长度的元组,那就太好了,尤其是在模板情况下。
例如,在当前的 Python3 中,解决方案是return (*f(...), *f(...)). C++ 中是否有与 Python 中类似的列表/元组解包运算符?
假设我有以下课程
class Example {
public:
using value_type = std::tuple<
uint8_t,
uint8_t,
uint16_t
>;
private:
value_type _value;
};
Run Code Online (Sandbox Code Playgroud)
现在,我希望能够基于此类型创建另一个类,将每个类类型包装在另一种类型中。基于将每种类型包装在模板化类中的可变参数模板中,我知道我可以通过以下方式实现一半的目标:
template <typename T>
class Wrapper;
template <typename ... ARGS>
class ExampleWrapper {
private:
std::tuple<Wrapper<ARGS>...> _args;
};
Run Code Online (Sandbox Code Playgroud)
但是,我无法弄清楚的是,ARGS如果我所知道的就是ExampleT在哪里,如何获取TExample。我希望能够使用ExampleWrapper如下:
ExampleWrapper<Example> myWrapper;
Run Code Online (Sandbox Code Playgroud)