代码如下
#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) 在尝试自己创建一个std::get<N>(std::tuple)方法后,我不太确定它是如何由编译器实现的.我知道std::tuple有这样的构造函数,
tuple(Args&&... args);
Run Code Online (Sandbox Code Playgroud)
但到底args...分配给了什么?我认为这对于知道如何std::get工作是有用的,因为需要将参数放在某处以便访问它们...
我正在尝试编写一个流运算符<<,它可以输出到一个std::tuple流而不是一个流.所以基本上,我试图tee用c ++ 编写Unix 命令,并且:
std::tie(std::cout,std::clog) << 1;
Run Code Online (Sandbox Code Playgroud)
我试图在c ++ 11中使用可变参数模板编程递归地编写流操作符.到目前为止我所拥有的内容如下面的代码所示.但是代码没有编译,错误信息很长.
我的问题是,如何修复代码使其工作?
编译g++ -std=c++11(gcc-4.8.1)的第一条错误消息是:
test.cpp:24:33: error: no match for 'operator<<' (operand types are 'std::tuple<std::basic_ostream<char, std::char_traits<char> >&, std::basic_ostream<char, std::char_traits<char> >&>' and 'int')
std::tie(std::cout,std::cout) << 1;
Run Code Online (Sandbox Code Playgroud)
PS我搜索了SO,并且有一些关于编写复合流对象的帖子.该代码涉及很多流和streambuf的内部.我在这里寻求的是一个简单/天真的解决方案,在十几行中完成类似的任务.
谢谢
我的代码:
#include <iostream>
#include <tuple>
template<typename _Value, typename Head, typename ... Tail>
struct _tee_stream {
static std::tuple<Head,Tail...>& _print(std::tuple<Head,Tail...>& _s, const _Value& _t) {
return std::make_tuple(std::get<0>(_s) << _t ,_tee_stream<Tail...,_Value>::_print(_s,_t));
}
};
template<typename _Value>
struct _tee_stream<_Value, std::tuple<>> {
static …Run Code Online (Sandbox Code Playgroud) 我想知道为什么要做出这个选择.它将允许以非常清晰和整洁的方式编写许多函数..例如:
int greatestCommonDivisor(int a, int b)
{
if (b > a)
std::tie(a, b) = { b, a };
while (b > 0)
std::tie(a, b) = { b, a % b };
return a;
}
Run Code Online (Sandbox Code Playgroud) 如何使用变量使用std :: get <>索引到元组?我有以下代码:
#include <iostream>
#include <tuple>
using namespace std;
int main() {
tuple<int, int> data(5, 10);
for (int i=0; i<2; i++) {
cout << "#" << i+1 << ":" << get<i>(data) << endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它失败并出现以下编译器错误:
prog.cpp: In function 'int main()':
prog.cpp:10:39: error: the value of 'i' is not usable in a constant expression
cout << "#" << i+1 << ":" << get<i>(data) << endl;
^
prog.cpp:9:11: note: 'int i' is not const
for …Run Code Online (Sandbox Code Playgroud) 鉴于std::tuple,
using Tuple1 = std::tuple<Foo1*, Bar1*, std::shared_ptr<std::mutex>>;
using Tuple2 = std::tuple<Foo2*, Bar2*, std::shared_ptr<std::mutex>>;
std::tuple<Tuple1, Tuple2> tuple;
Run Code Online (Sandbox Code Playgroud)
而功能,
void baz()
{
auto tup = std::get<0>(tuple);
std::lock_guard<std::mutex> lk(*std::get<2>(tup));
// Do something with std::get<0>(tup) and std::get<1>(tup)
}
Run Code Online (Sandbox Code Playgroud)
根据这个关于SO的问题,访问a std::tuple本身并不是线程安全的,但是在示例代码的情况下呢?是否有可能发生未定义/奇怪的事情?
这是假设FooN&BarN只能在锁定后访问.
我正在尝试编写模板函数/运算符,例如+在两个相同类型的元组之间进行算术运算.例如,对于
std::tuple<int,double> t = std::make_tuple(1,2);
Run Code Online (Sandbox Code Playgroud)
我想做
auto t1 = t + t;
Run Code Online (Sandbox Code Playgroud)
逻辑很简单:按顺序进行算术运算.但我无法弄清楚如何在c ++模板编程中完成这项工作(c ++ 11/17).我下面的代码不能编译g++ -std=c++11 tuple_arith.cpp.特别是,我无法弄清楚使用泛型add函数(template<typename T> T add(T x, T y) { return x + y; })来处理元组操作代码的正确方法.
有人可以帮助解释如何解决问题吗?
#include <tuple>
namespace std {
template<typename _Tp, size_t __i, size_t __size, typename _opT >
struct __tuple_arith {
static constexpr _Tp __op(const _Tp& __t, const _Tp& __u, const _opT& op) {
return std::tuple_cat(std::make_tuple(op(std::get<__i>(__t), std::get<__i>(__u))
, __tuple_arith<_Tp, __i + 1, __size, _opT>::__op(__t, __u))); …Run Code Online (Sandbox Code Playgroud) 我试图返回一个std::tuple包含不可复制构造类型的元素的。这似乎阻止了我使用默认的类构造函数构造元组。例如,要返回一个包含的元组Foo,foo必须创建一个实例并创建std::moved:
class Foo {
public:
Foo(const Foo&) = delete;
Foo(Foo&&) = default;
int x;
};
tuple<int, Foo> MakeFoo() {
Foo foo{37};
// return {42, {37}}; // error: could not convert ‘{42, {37}}’ from ‘’ to ‘std::tuple’
return {42, std::move(foo)};
}
Run Code Online (Sandbox Code Playgroud)
另一方面,如果将类定义为具有副本构造函数,则元组的构造可以正常工作:
class Bar {
public:
Bar(const Bar&) = default;
int x;
};
tuple<int, Bar> MakeBar() {
return {42, {37}}; // compiles ok
}
Run Code Online (Sandbox Code Playgroud)
有没有办法MakeBar在Foo类中使用语法?