参考元组初始化引用元组 [英] Initialize tuple of references with reference to tuple

查看:40
本文介绍了参考元组初始化引用元组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有代码

#include <元组>使用 Vec3 = std::tuple;使用 Vec3Ref = std::tuple<float&, float&, float>;空的东西(){vec3 foo (0,0,0);Vec3Ref 栏 (foo);}

我收到错误

/usr/include/c++/4.6/tuple:100:4: 错误:将引用绑定到类型float"到'const float' 类型的值删除限定符: _M_head_impl(std::forward<_UHead>(__h)) { }^ ~~~~~~~~~~~~~~~~~~~~~~~~~//剪.../usr/include/c++/4.6/tuple:257:11: 注意:在函数模板的实例化中专业化 'std::_Tuple_impl<0, float &, float &, float &>::_Tuple_impl<浮动,浮动,浮动>'在这里请求: _Inherited(static_cast&>(__in))^18:注意:在函数模板特化的实例化中'std::tuple::tuple' 在这里请求Vec3Ref 栏 (foo);^

我发现的最接近的是 这个问题,但问题似乎是用从 std::make_tuple 返回的元组进行初始化,这是一个右值.然而,foo 在很大程度上是一个左值.为什么这不起作用?这与使用 std::tie 有何不同?

解决方案

Github 草稿于 2014-07-23,[tuple.cnstr]

<块引用>

template constexpr 元组(元组&& u);

18 要求: sizeof...(Types) == sizeof...(UTypes).is_constructible 对于所有 i 来说都是 true.

20 备注: 此构造函数不参与除非UTypes 中的每个类型都是隐式的,否则重载决议可转换为 Types 中对应的类型.

备注: 部分定义了 SFINAE.请注意它与 Requires: 部分的不同之处在于它要求使用 is_convertible 而不是 is_constructible.

在 OP 的示例中,这导致检查 is_convertible,这是错误的:float xvalue 不能绑定到 float 左值参考:

is_convertible [meta.rel]/4

<块引用>

给定以下函数原型:

template add_rvalue_reference_t::type create() noexcept;

模板特化的谓词条件 is_convertible 应满足当且仅当以下 vode 格式正确,包括任何隐式转换到函数的返回类型:

测试(){返回 create();}

这里,

float&测试() {return create();}

格式错误,create() 返回一个 float&&,即一个 xvalue.结果不能绑定到左值引用.

<小时>

众所周知,tuple的构造并不完美;参见例如提案N3680,其中还解决了 LWG 缺陷 2051.

然而,这些似乎都没有解决 OP 中的问题.

If I have the code

#include <tuple>

using Vec3 = std::tuple<float, float, float>;
using Vec3Ref = std::tuple<float&, float&, float&>;

void stuff ()
{
  Vec3 foo (0,0,0);
  Vec3Ref bar (foo);
}

I get the error

/usr/include/c++/4.6/tuple:100:4: error: binding of reference to type 'float' to
a value of type 'const float' drops qualifiers

: _M_head_impl(std::forward<_UHead>(__h)) { }

^ ~~~~~~~~~~~~~~~~~~~~~~~~~

//snip...

/usr/include/c++/4.6/tuple:257:11: note: in instantiation of function template
specialization 'std::_Tuple_impl<0, float &, float &, float &>::_Tuple_impl
<float, float, float>' requested here

: _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))

^

18 : note: in instantiation of function template specialization
'std::tuple::tuple' requested here

Vec3Ref bar (foo);

^

The closest thing I've found is this question, but the problem there seems to be about initializing with a tuple returned from std::make_tuple, which is an rvalue. foo, however, is very much an lvalue. Why does this not work? How is this different from using std::tie?

解决方案

Github draft from 2014-07-23, [tuple.cnstr]

template <class... UType> constexpr tuple(tuple<UTypes...>&& u);

18 Requires: sizeof...(Types) == sizeof...(UTypes). is_constructible<Ti, Ui&&>::value is true for all i.

20 Remark: This constructor shall not participate in overload resolution unless each type in UTypes is implicitly convertible to its corresponding type in Types.

The Remarks: section defines the SFINAE. Note how it's different from the Requires: section by requiring the use of is_convertible instead of is_constructible.

In the OP's example, this leads to the check is_convertible<float, float&>, which is false: a float xvalue cannot be bound to a float lvalue reference:

is_convertible [meta.rel]/4

Given the following function prototype:

template <class T>
add_rvalue_reference_t<T>::type create() noexcept;

the predicate condition for a template specialization is_convertible<From, To> shall be satisfied if and only if the following vode would be well-formed, including any implicit conversions to the return type of the function:

To test() {
    return create<From>();
}

Here,

float& test() {
    return create<float>();
}

is ill-formed, create<float>() returns a float&&, that is, an xvalue. The result cannot be bound to an lvalue-reference.


It is well-known that the construction of tuple is not perfect; see for example proposal N3680, which also addresses LWG defect 2051.

None of those seem to address the issue in the OP, however.

这篇关于参考元组初始化引用元组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆