通过使用显式构造函数将相同的参数传递给每个元素来构造元组 [英] Construct tuple by passing the same argument to each element with explicit constructor

查看:58
本文介绍了通过使用显式构造函数将相同的参数传递给每个元素来构造元组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下内容在Visual C ++ 2015 Update 2上正常运行.请注意, A 是不可复制的,而 A :: A explicit .

The following works fine on Visual C++ 2015 Update 2. Note that A is non-copyable and A::A is explicit.

#include <iostream>
#include <tuple>

struct A
{
    explicit A(int i)
    {
        std::cout << i << " ";
    }

    // non-copyable
    A(const A&) = delete;
    A& operator=(const A&) = delete;
};


template <class... Ts>
struct B
{
    std::tuple<Ts...> ts;

    B(int i)
      : ts((sizeof(Ts), i)...)
    {
    }
};


int main()
{
    B<A, A, A, A> b(42);
}

目标是将相同的参数传递给所有元组元素.正确输出:

The goal is to pass the same argument to all tuple elements. It correctly outputs:

42 42 42 42

但是,它无法在g ++ 4.9.2上编译.在许多消息中,我认为应该称为 tuple 构造函数重载:

However, it fails to compile on g++ 4.9.2. Among the many messages is the tuple constructor overload that I think should be called:

In instantiation of ‘B<Ts>::B(int) [with Ts = {A, A, A, A}]’:
    33:24:   required from here
    25:30: error: no matching function for call to
       ‘std::tuple<A, A, A, A>::tuple(int&, int&, int&, int&)’
          : ts((sizeof(Ts), i)...)

[...]

/usr/include/c++/4.9/tuple:406:19: note: template<class ... _UElements, class>
    constexpr std::tuple< <template-parameter-1-1> >::tuple(_UElements&& ...)
     constexpr tuple(_UElements&&... __elements)
               ^
/usr/include/c++/4.9/tuple:406:19: note:   template argument deduction/substitution failed:
/usr/include/c++/4.9/tuple:402:40: error: no type named ‘type’ in
    ‘struct std::enable_if<false, void>’
       template<typename... _UElements, typename = typename

消息中的功能签名不完整,但它引用了以下内容:

The function signature is incomplete in the message, but it refers to this one:

template<typename... _UElements, typename = typename               
   enable_if<__and_<is_convertible<_UElements,
                   _Elements>...>::value>::type>                        
explicit constexpr tuple(_UElements&&... _elements)                      
     : _Inherited(std::forward<_UElements>(__elements)...) { }    

我的理解是,对于显式构造函数, is_convertible 失败.g ++ 5.1和clang 3.5具有类似的错误消息.

My understanding is that is_convertible fails for an explicit constructor. g++ 5.1 and clang 3.5 have similar error messages.

现在,在C ++ 14中,20.4.2.1/10说:除非 UTypes 中的每种类型都隐式转换为中的相应类型,否则该构造函数不得参与重载解析.类型".这给我的印象是g ++和clang实际上拥有这项权利,而Visual C ++则过于宽容.

Now, in C++14, 20.4.2.1/10 says: "This constructor shall not participate in overload resolution unless each type in UTypes is implicitly convertible to its corresponding type in Types". This gives me the impression that g++ and clang actually have this right and that Visual C++ is overly permissive.

[edit:看来C ++ 17删除了此限制,而Visual C ++ 2015遵循了此限制.它现在说:除非所有的[...] is_constructible< Ti,Ui&& :: value true ,否则该构造函数不得参与重载解析. i ."看起来可隐式转换"已更改为" is_constructible ".但是,我仍然需要C ++ 14解决方案.]

[edit: It appears that C++17 has removed this restriction and that Visual C++ 2015 follows it. It now says: "This constructor shall not participate in overload resolution unless [...] is_constructible<Ti, Ui&&>::value is true for all i." It looks like "is implicitly convertible" was changed to "is_constructible". However, I still need a C++14 solution.]

我尝试从构造函数中删除 explicit (我希望保留它).Visual C ++再次可以正常编译,但是g ++和clang都抱怨已删除的副本构造函数.因为 int 现在可以隐式转换为 A ,所以我似乎最终会遇到

I tried removing explicit from the constructor (I'd prefer to keep it). Visual C++ again compiles fine, but both g++ and clang complain about the deleted copy constructor. Because int is now implicitly convertible to an A, I seem to end up in

explicit constexpr tuple(const Types&...)

会将 int s隐式转换为一堆 A s,然后尝试复制它们.我实际上不确定我将如何使用其他构造函数.

which would implicitly convert the ints into a bunch of As and then try to copy them. I'm actually not sure how I would ever be able to use the other constructor.

在C ++ 14中,如果构造函数是 explicit ,如何通过将相同的参数传递给每个构造函数来获取 tuple 来初始化其元素?

In C++14, how can I get tuple to initialize its elements by passing the same argument to each constructor if the constructors are explicit?

推荐答案

在C ++ 14中,由于 is_convertible ,当构造函数是显式的时,似乎没有任何初始化元组元素的方法.要求.我最终自己写了一个 std :: tuple 的准系统实现,该实现用于C ++ 14实现,例如Debian 8.

In C++ 14, there doesn't seem to be any way of initializing tuple elements when constructors are explicit, because of the is_convertible requirement. I ended up writing a bare-bones implementation of std::tuple myself that is used on C++14 implementations, such as on Debian 8.

这篇关于通过使用显式构造函数将相同的参数传递给每个元素来构造元组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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