我想知道是否可以使用以下事实
struct Foo
{
int x;
};
int main()
{
Foo foo;
auto [a0] = foo;
auto [a1, b1] = foo;
auto [a2, b2, c2] = foo;
// auto [a, b, c, ...] = foo;
}
Run Code Online (Sandbox Code Playgroud)
只有第一个结构化绑定是有效的,以便创建接受任何 pod 类型并返回由传递的 pod 的所有成员类型组成的元组,例如,对于 Foo 它将返回
std::tuple<int>
Run Code Online (Sandbox Code Playgroud)
我试过这样的事情,但没有奏效:
#include <tuple>
#include <type_traits>
#include <utility>
using namespace std;
template<typename T, typename U = void>
struct to_tuple;
template<typename T>
struct to_tuple<T, void_t<decltype([](T x) {
auto [a] = x;
return make_tuple(a);
}(declval<T>()))>>
{
using type = decltype([](T x) {
auto [a] = x;
return make_tuple(a);
}(declval<T>()));
};
template<typename T>
struct to_tuple<T, void_t<decltype([](T x) {
auto [a, b] = x;
return make_tuple(a, b);
}(declval<T>()))>>
{
using type = decltype([](T x) {
auto [a, b] = x;
return make_tuple(a, b);
}(declval<T>()));
};
template<typename T>
using to_tuple_t = typename to_tuple<T>::type;
struct Bar1
{
int x;
};
struct Bar2
{
int x;
float y;
};
int main()
{
static_assert(is_same_v<to_tuple_t<Bar1>, tuple<int>>);
static_assert(is_same_v<to_tuple_t<Bar2>, tuple<int, float>>);
}
Run Code Online (Sandbox Code Playgroud)
这里的主要问题是结构化绑定声明就是一个声明。我们无法形成“结构化绑定表达式”来获取类型,这是元编程中约束模板所需的类型(例如,模式void_t或concept/requires子句)
根据[dcl.struct.bnd],尽管存在赋值表达式,但结构化绑定显然是一个声明。
模板元编程依赖于types,并且声明没有类型。例如,您不能说decltype(int a = 10)或什至decltype(int a)出于这个原因。
你可以说decltype(int{})因为现在我们有一个表达式。因此,您的void_t模式不起作用。
不幸的是,概念/约束对我们没有帮助,因为我们不能在 require 子句中进行声明(根据[gram.expr])
就我个人而言,我认为这是一个疏忽,我们无法拥有int{}与结构化绑定相同的功能。但话又说回来,反思无论如何都在进行中,所以这一点可能没有实际意义。
编辑:正如dfri 指出的那样,有一个称为语句表达式的 GNU 扩展可以使这成为可能(作为扩展,它是可以理解的不可移植代码)
| 归档时间: |
|
| 查看次数: |
307 次 |
| 最近记录: |