簡體   English   中英

通過使用顯式構造函數將相同的參數傳遞給每個元素來構造元組

[英]Construct tuple by passing the same argument to each element with explicit constructor

以下內容在Visual C ++ 2015 Update 2上正常運行。請注意, A是不可復制的,而A::Aexplicit

#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);
}

目標是將相同的參數傳遞給所有元組元素。 正確輸出:

42 42 42 42

但是,它無法在g ++ 4.9.2上進行編譯。 我認為應該在眾多消息中包含tuple構造函數重載:

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

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

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具有類似的錯誤消息。

現在,在C ++ 14中,20.4.2.1/10表示:“除非UTypes每個類型UTypes可以隱式轉換為Types相應類型,否則該構造函數不得參與重載解析”。 這給我的印象是g ++和clang實際上擁有這項權利,而Visual C ++則過於寬容。

[編輯:看來C ++ 17刪除了此限制,而Visual C ++ 2015遵循了此限制。 現在它說:“除非is_constructible<Ti, Ui&&>::value對所有itrue ,否則該構造函數均不得參與重載解析。” 看起來“可隱式轉換”已更改為“ is_constructible ”。 但是,我仍然需要C ++ 14解決方案。]

我嘗試從構造函數中刪除explicit (我希望保留它)。 Visual C ++再次可以正常編譯,但是g ++和clang都抱怨已刪除的副本構造函數。 因為int現在可以隱式轉換為A ,所以我似乎最終以

explicit constexpr tuple(const Types&...)

這會將int隱式轉換為一堆A ,然后嘗試復制它們。 我實際上不確定如何使用其他構造函數。

在C ++ 14中,如果構造函數是explicit ,如何通過將相同的參數傳遞給每個構造函數來使tuple初始化其元素?

在C ++ 14中,由於is_convertible要求,當構造函數是顯式的時,似乎沒有任何初始化元組元素的is_convertible 我最終自己寫了一個std::tuple實現,該實現用於C ++ 14實現,例如Debian 8。

我與gcc 4.9.2的錯誤與您不同:

main_console.cpp:47:30: error: no matching function for call to 'std::tuple<A, A, A, A>::tuple(int&, int&, int&, int&)' ts((sizeof(Ts), i)...)

問題出在構造函數B(int i) : ts((sizeof(Ts), i)...) { }而且我不知道您的構造函數如何工作。

B構造函數看起來像: B(int i) : ts(Ts(i)...) { }並且在A使用復制構造函數時,它對我來說很好用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM