Variation template question

I have the following code that I am trying to adapt for my purposes. This is an exercise for me to try to upgrade my C ++ skills. To my knowledge, this was originally written by Clang 3.1.

I tried compiling with versions of Clang from 3.1 to 4.0 and GCC 4.9 to 7.1 with very similar results.

These are the error messages from GCC 5.1

Error 1: In instantiation of 'constexpr Struct<Fields>::Struct(T&& ...) [with T = {Struct<foo<int>, bar<double> >&}; Fields = {foo<int>, bar<double>}]':
<source>:46:12:   required from here

Error 2: <source>:28:61: error: mismatched argument pack lengths while expanding 'Fields'
 constexpr Struct(T &&...x) : Fields{static_cast<T&&>(x)}... {}

Please ELI5 if you have the patience: P

You can see it in the godbolts doohickey compiler here: https://godbolt.org/g/2dRPXf

EDIT:

Given the answers from @ Passer-By and @ Daniel-Jour, I wonder if it is required Struct(Struct const &) = default;. Removing this constructor from Structhas consequences that I do not know about or did not foresee (I'm not C ++ Swami!)?

constexpr Struct(T &&...x) : Fields{static_cast<T&&>(x)}... {} , Struct(Struct const &) = default;?

.

EDIT

// From http://duriansoftware.com/joe/Self-aware-struct-like-types-in-C++11.html
// edited a bit to stop the compiler whining about comments in multiline macros
#include <type_traits>
#include <utility>

#define SELFAWARE_IDENTIFIER(NAME) \
    template<typename T> \
    struct NAME { \
        T NAME; /* field name */ \
        constexpr static char const *name() { return #NAME; } /* field type */ \
        using type = T; /* field value generic accessor */ \
        T &value() & { return this->NAME; } \
        T const &value() const & { return this->NAME; } \
        T &&value() && { return this->NAME; } \
    };

template<typename...Fields>
struct Struct : Fields... {
    // A convenience alias for subclasses
    using struct_type = Struct;

    // Preserve default constructors
    Struct() = default;
    Struct(Struct const &) = default;

    // Forwarding elementwise constructor
    template<typename...T>
    constexpr Struct(T &&...x) : Fields{static_cast<T&&>(x)}... {} // Error 2 here
};

SELFAWARE_IDENTIFIER(foo)
SELFAWARE_IDENTIFIER(bar)
// Aliasing a Struct instance
using FooBar = Struct<foo<int>, bar<double> >;
// Inheriting a Struct instance (requires inheriting constructors)
struct FooBar2 : Struct<foo<int>, bar<double>> { using struct_type::struct_type; };

static_assert(std::is_trivial<FooBar>::value, "should be trivial");
static_assert(FooBar{2, 3.0}.foo + FooBar{2, 4.0}.foo == 4, "2 + 2 == 4");


FooBar frob(int x) {
    FooBar f = {x, 0.0};
    f.foo += 1;
    f.bar += 1.0;
    return f; // Error 1 here
}
+6
2

, " " .

, :

constexpr Struct<Fields>::Struct(T&& ...) [ T = {Struct<foo<int>, bar<double> >&}; Fields = {foo<int>, bar<double>}]:

,

return f;

, .

, , , Struct. - . , Struct<foo<int>, bar<double> >&. Fields ( ), :

[..] : [..]

, ? ( ), ( Struct(Struct const &)): Struct(Struct & &&), Struct(Struct &). , f return f;: f non const lvalue.

- () :

Struct(Struct & s)
  : Struct(static_cast<Struct const &>(s))
{}

volatile, , . .

- SFINAE:

template<typename T>
using decay_t = typename decay<T>::type;

template<
  typename...T,
  std::enable_if<
    (sizeof...(T) == sizeof...(Fields))
    && not_self_helper<Struct, std::tuple<decay_t<T>...>>::value
    >::type * = nullptr
  >
constexpr Struct(T &&...x)
  : Fields{static_cast<T&&>(x)}... {}

not_self_helper , , , :

template<typename, typename>
struct not_self_helper : std::true_type {};

template<typename Self>
struct not_self_helper<Self, std::tuple<Self>> : std::false_type {};

: . , , . , ( , ). , , , . , , "" : /.

+1

template<typename... Args>
Struct(Args&&...);

lvalue, Args lvalue rvalue rvalue.

, constrcutor , .

, ,

Struct(const Struct&);

Lvalue const Struct const Struct&, lvalue rvalue Struct varadic Struct& Struct&& .

glvalue, , return, xvalue Struct&& . , lvalue Struct& const Struct&.

Struct&& , .

, , .

, , .

Variadic- , , , ( 2) , , : ""

, , , SFINAE , .

+1

All Articles