2016-05-14 9 views
-2

Hier ist, was ich bisher für eine beispielhafte Implementierung eines benutzerdefinierten Konstruktor im Stil std::pair::pair(std::piecewise_construct_t, ...) haben:Wie kann ich meinen eigenen Konstruktor "stackwise_construct" erstellen?

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

Erwartete Ausgabe (wenn verrohrt durch cat -v):

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

jedoch gcc ist nach wie vor gibt mir Fehler, die ich nicht ganz entschlüsseln kann, die auf die interne Implementierung von std::tuple bezogen zu sein scheinen:

/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

umfassen die Fehlermeldung in der Frage selbst –

+0

@PiotrSkotnicki Fertig. –

Antwort

1

Whoops, es sieht so aus, als ob ich nur ein bisschen mehr Geduld brauchte, um die Fehlermeldungen zu betrachten. Wenn ich mir nur die erste angesehen hätte, hätte sie mir gesagt, dass std::tuple<int&&, char&&> einen implizit gelöschten Kopierkonstruktor hat, vermutlich wegen der rvalue-Referenz-Member. Also, wenn ich die Überladung unter Dummy integer_sequence Objekte ändern, um tuple Referenzen zu nehmen, dann kompiliert das Beispiel.

Aber dann, im Fall des zweiten Elements, sieht es so aus, als ob es den Konstruktor initializer_list anstelle des beabsichtigten Konstruktors size_t, char verwendet. Der Wechsel von geschweiften Initialisierern zu den ursprünglichen initialisierten Klammern in Klammern in derselben Überladung hat das behoben.

Also insgesamt ersetzen, dass die Überlastung mit:

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))...) 
    { } 
Verwandte Themen