2016-05-14 101 views
-2

這裏是我迄今爲止在的std::pair::pair(std::piecewise_construct_t, ...)風格的示例實現自定義構造函數:如何製作我自己的piecewise_construct構造函數?

#include <tuple> 
#include <string> 
#include <utility> 
#include <iostream> 

struct A { 
    std::string m_a; 
    std::string m_b; 
    std::string m_c; 

    A() = default; 
    A(const A&) = default; 
    A(A&&) = default; 
    ~A() = default; 

    template <typename T1, typename T2, typename T3> 
    A(T1&& a, T2&& b, T3&& c) : 
    m_a { std::forward<T1>(a) }, m_b { std::forward<T2>(b) }, m_c { std::forward<T3>(c) } 
    { } 

    template <typename... T1, typename... T2, typename... T3, 
      std::size_t... I1, std::size_t... I2, std::size_t... I3> 
    A(std::tuple<T1...> args1, 
    std::tuple<T2...> args2, 
    std::tuple<T3...> args3, 
    std::integer_sequence<std::size_t, I1...>, 
    std::integer_sequence<std::size_t, I2...>, 
    std::integer_sequence<std::size_t, I3...>) : 
    m_a { std::forward<T1>(std::get<I1>(args1))... }, 
    m_b { std::forward<T2>(std::get<I2>(args2))... }, 
    m_c { std::forward<T3>(std::get<I3>(args3))... } 
    { } 

    template <typename... T1, typename... T2, typename... T3> 
    A(std::piecewise_construct_t, 
    std::tuple<T1...> args1, 
    std::tuple<T2...> args2, 
    std::tuple<T3...> args3) : 
    A { args1, args2, args3, 
     std::make_index_sequence<sizeof...(T1)>{}, 
     std::make_index_sequence<sizeof...(T2)>{}, 
     std::make_index_sequence<sizeof...(T3)>{} } 
    { } 
}; 

int main() { 
    A a { std::piecewise_construct, 
     std::forward_as_tuple("abc"), 
     std::forward_as_tuple(10, 'd'), 
     std::forward_as_tuple("ef\0\0gh", 6) 
     }; 
    std::cout << "m_a: " << a.m_a << 
    "\nm_b: " << a.m_b << 
    "\nm_c: " << a.m_c << '\n'; 
    return 0; 
} 

預期輸出(如果通過cat -v管道):

m_a: abc 
m_b: dddddddddd 
m_c: ef^@^@gh 

然而,GCC仍然給我錯誤,我不能完全破譯,這似乎與std::tuple的內部執行有關:

/tmp/from_tuple.cpp: In instantiation of ‘A::A(std::piecewise_construct_t, std::tuple<_Elements ...>, std::tuple<_Elements ...>, std::tuple<_Tail ...>) [with T1 = {const char (&)[4]}; T2 = {int&&, char&&}; T3 = {const char (&)[7], int&&}]’: 
/tmp/from_tuple.cpp:51:11: required from here 
/tmp/from_tuple.cpp:42:53: error: use of deleted function ‘constexpr std::tuple<_T1, _T2>::tuple(const std::tuple<_T1, _T2>&) [with _T1 = int&&; _T2 = char&&]’ 
      std::make_index_sequence<sizeof...(T3)>{} } 
                ^
In file included from /tmp/from_tuple.cpp:1:0: 
/usr/include/c++/5/tuple:615:17: note: ‘constexpr std::tuple<_T1, _T2>::tuple(const std::tuple<_T1, _T2>&) [with _T1 = int&&; _T2 = char&&]’ is implicitly deleted because the default definition would be ill-formed: 
     constexpr tuple(const tuple&) = default; 
       ^
/usr/include/c++/5/tuple:615:17: error: use of deleted function ‘constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const std::_Tuple_impl<_Idx, _Head, _Tail ...>&) [with long unsigned int _Idx = 0ul; _Head = int&&; _Tail = {char&&}]’ 
/usr/include/c++/5/tuple:215:17: note: ‘constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const std::_Tuple_impl<_Idx, _Head, _Tail ...>&) [with long unsigned int _Idx = 0ul; _Head = int&&; _Tail = {char&&}]’ is implicitly deleted because the default definition would be ill-formed: 
     constexpr _Tuple_impl(const _Tuple_impl&) = default; 
       ^
/usr/include/c++/5/tuple:215:17: error: use of deleted function ‘constexpr std::_Tuple_impl<_Idx, _Head>::_Tuple_impl(const std::_Tuple_impl<_Idx, _Head>&) [with long unsigned int _Idx = 1ul; _Head = char&&]’ 
/usr/include/c++/5/tuple:364:17: note: ‘constexpr std::_Tuple_impl<_Idx, _Head>::_Tuple_impl(const std::_Tuple_impl<_Idx, _Head>&) [with long unsigned int _Idx = 1ul; _Head = char&&]’ is implicitly deleted because the default definition would be ill-formed: 
     constexpr _Tuple_impl(const _Tuple_impl&) = default; 
       ^
/usr/include/c++/5/tuple:364:17: error: use of deleted function ‘constexpr std::_Head_base<_Idx, _Head, false>::_Head_base(const std::_Head_base<_Idx, _Head, false>&) [with long unsigned int _Idx = 1ul; _Head = char&&]’ 
/usr/include/c++/5/tuple:110:17: note: ‘constexpr std::_Head_base<_Idx, _Head, false>::_Head_base(const std::_Head_base<_Idx, _Head, false>&) [with long unsigned int _Idx = 1ul; _Head = char&&]’ is implicitly deleted because the default definition would be ill-formed: 
     constexpr _Head_base(const _Head_base&) = default; 
       ^
/usr/include/c++/5/tuple:110:17: error: copying non-static data member ‘char&& std::_Head_base<1ul, char&&, false>::_M_head_impl’ of rvalue reference type 
/usr/include/c++/5/tuple:215:17: error: use of deleted function ‘constexpr std::_Head_base<_Idx, _Head, false>::_Head_base(const std::_Head_base<_Idx, _Head, false>&) [with long unsigned int _Idx = 0ul; _Head = int&&]’ 
     constexpr _Tuple_impl(const _Tuple_impl&) = default; 
       ^
/usr/include/c++/5/tuple:110:17: note: ‘constexpr std::_Head_base<_Idx, _Head, false>::_Head_base(const std::_Head_base<_Idx, _Head, false>&) [with long unsigned int _Idx = 0ul; _Head = int&&]’ is implicitly deleted because the default definition would be ill-formed: 
     constexpr _Head_base(const _Head_base&) = default; 
       ^
/usr/include/c++/5/tuple:110:17: error: copying non-static data member ‘int&& std::_Head_base<0ul, int&&, false>::_M_head_impl’ of rvalue reference type 
/tmp/from_tuple.cpp:23:7: note: initializing argument 2 of ‘A::A(std::tuple<_Elements ...>, std::tuple<_Elements ...>, std::tuple<_Tail ...>, std::integer_sequence<long unsigned int, I1 ...>, std::integer_sequence<long unsigned int, I2 ...>, std::integer_sequence<long unsigned int, I3 ...>) [with T1 = {const char (&)[4]}; T2 = {int&&, char&&}; T3 = {const char (&)[7], int&&}; long unsigned int ...I1 = {0ul}; long unsigned int ...I2 = {0ul, 1ul}; long unsigned int ...I3 = {0ul, 1ul}]’ 
     A(std::tuple<T1...> args1, 
    ^
/tmp/from_tuple.cpp:42:53: error: use of deleted function ‘constexpr std::tuple<_T1, _T2>::tuple(const std::tuple<_T1, _T2>&) [with _T1 = const char (&)[7]; _T2 = int&&]’ 
      std::make_index_sequence<sizeof...(T3)>{} } 
                ^
In file included from /tmp/from_tuple.cpp:1:0: 
/usr/include/c++/5/tuple:615:17: note: ‘constexpr std::tuple<_T1, _T2>::tuple(const std::tuple<_T1, _T2>&) [with _T1 = const char (&)[7]; _T2 = int&&]’ is implicitly deleted because the default definition would be ill-formed: 
     constexpr tuple(const tuple&) = default; 
       ^
/usr/include/c++/5/tuple:615:17: error: use of deleted function ‘constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const std::_Tuple_impl<_Idx, _Head, _Tail ...>&) [with long unsigned int _Idx = 0ul; _Head = const char (&)[7]; _Tail = {int&&}]’ 
/usr/include/c++/5/tuple:215:17: note: ‘constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const std::_Tuple_impl<_Idx, _Head, _Tail ...>&) [with long unsigned int _Idx = 0ul; _Head = const char (&)[7]; _Tail = {int&&}]’ is implicitly deleted because the default definition would be ill-formed: 
     constexpr _Tuple_impl(const _Tuple_impl&) = default; 
       ^
/usr/include/c++/5/tuple:215:17: error: use of deleted function ‘constexpr std::_Tuple_impl<_Idx, _Head>::_Tuple_impl(const std::_Tuple_impl<_Idx, _Head>&) [with long unsigned int _Idx = 1ul; _Head = int&&]’ 
/usr/include/c++/5/tuple:364:17: note: ‘constexpr std::_Tuple_impl<_Idx, _Head>::_Tuple_impl(const std::_Tuple_impl<_Idx, _Head>&) [with long unsigned int _Idx = 1ul; _Head = int&&]’ is implicitly deleted because the default definition would be ill-formed: 
     constexpr _Tuple_impl(const _Tuple_impl&) = default; 
       ^
/usr/include/c++/5/tuple:364:17: error: use of deleted function ‘constexpr std::_Head_base<_Idx, _Head, false>::_Head_base(const std::_Head_base<_Idx, _Head, false>&) [with long unsigned int _Idx = 1ul; _Head = int&&]’ 
/usr/include/c++/5/tuple:110:17: note: ‘constexpr std::_Head_base<_Idx, _Head, false>::_Head_base(const std::_Head_base<_Idx, _Head, false>&) [with long unsigned int _Idx = 1ul; _Head = int&&]’ is implicitly deleted because the default definition would be ill-formed: 
     constexpr _Head_base(const _Head_base&) = default; 
       ^
/usr/include/c++/5/tuple:110:17: error: copying non-static data member ‘int&& std::_Head_base<1ul, int&&, false>::_M_head_impl’ of rvalue reference type 
/tmp/from_tuple.cpp:23:7: note: initializing argument 3 of ‘A::A(std::tuple<_Elements ...>, std::tuple<_Elements ...>, std::tuple<_Tail ...>, std::integer_sequence<long unsigned int, I1 ...>, std::integer_sequence<long unsigned int, I2 ...>, std::integer_sequence<long unsigned int, I3 ...>) [with T1 = {const char (&)[4]}; T2 = {int&&, char&&}; T3 = {const char (&)[7], int&&}; long unsigned int ...I1 = {0ul}; long unsigned int ...I2 = {0ul, 1ul}; long unsigned int ...I3 = {0ul, 1ul}]’ 
     A(std::tuple<T1...> args1, 
    ^
+4

包括在問題本身 –

+0

@PiotrSkotnicki完成的錯誤消息。 –

回答

1

哎呀,看起來我只是需要更多的耐心看錯誤信息。如果我只看了第一個,它告訴我std::tuple<int&&, char&&>有一個隱式刪除的拷貝構造函數,大概是因爲右值引用成員。所以,如果我改變過載,假設integer_sequence對象採取tuple引用,那麼該示例編譯。

但是,在第二個元素的情況下,它看起來像是使用構造函數initializer_list而不是構造函數size_t, char。從括號初始值設定項更改爲舊式括號初始值設定項,在相同的過載中修正了該值。

所以,總體來說,與更換過載:

template <typename... T1, typename... T2, typename... T3, 
      std::size_t... I1, std::size_t... I2, std::size_t... I3> 
    A(std::tuple<T1...>& args1, 
    std::tuple<T2...>& args2, 
    std::tuple<T3...>& args3, 
    std::integer_sequence<std::size_t, I1...>, 
    std::integer_sequence<std::size_t, I2...>, 
    std::integer_sequence<std::size_t, I3...>) : 
    m_a(std::forward<T1>(std::get<I1>(args1))...), 
    m_b(std::forward<T2>(std::get<I2>(args2))...), 
    m_c(std::forward<T3>(std::get<I3>(args3))...) 
    { }