Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

This is not copy-initializing, or is it?

In the following code I am not allowed to declare an explicit ctor because the compiler says I am using it in a copy-initializing context (clang 3.3 and gcc 4.8). I try to prove the compilers wrong by making the ctor non explicit and then declaring the copy constructors as deleted.

Are the compilers wrong or is there any other explanation?

#include <iostream>

template <typename T>
struct xyz
{
    constexpr xyz (xyz const &)    = delete;
    constexpr xyz (xyz &&)         = delete;
    xyz & operator = (xyz const &) = delete;
    xyz & operator = (xyz &&)      = delete;
    T i;
    /*explicit*/ constexpr xyz (T i): i(i) { }
};

template <typename T>
xyz<T> make_xyz (T && i)
{
    return {std::forward<T>(i)};
}

int main ()
{
    //auto && x = make_xyz(7);
    auto && x (make_xyz(7)); // compiler sees copy-initialization here too
    std::cout << x.i << std::endl;
}

Update An unrealistic but much simpler version

struct xyz {
    constexpr xyz (xyz const &) = delete;
    constexpr xyz (xyz &&) = delete;
    xyz & operator = (xyz const &) = delete;
    xyz & operator = (xyz &&) = delete;
    int i;
    explicit constexpr xyz (int i): i(i) { }
};

xyz make_xyz (int && i) {
    return {i};
}

int main () {
    xyz && x = make_xyz(7); 
}
like image 508
Patrick Fromberg Avatar asked Dec 13 '13 05:12

Patrick Fromberg


People also ask

What is copy initialization?

This assigns the value of one object to another object both of which are already exists. Copy initialization is used when a new object is created with some existing object. This is used when we want to assign existing object to new object.

What is the other name for copy initialization?

A copy constructor is a member function that initializes an object using another object of the same class. In simple terms, a constructor which creates an object by initializing it with an object of the same class, which has been created previously is known as a copy constructor.

How does copy elision work?

Copy elision is the general process where, when returned from a function, an object is not copied nor moved, resulting in zero-copy pass-by-value semantics. It includes both return value optimization (RVO) and named return value optimization (NRVO).


1 Answers

The = notation should not affect the complaint because reference binding doesn't behave differently whether expressed by direct- or copy-initialization. What's being initialized here is the return value object, which does not have its own name.

Unfortunately, GCC is right to complain, as does Clang. According to §6.6.3/2 [stmt.return],

A return statement with a braced-init-list initializes the object or reference to be returned from the function by copy-list-initialization (8.5.4) from the specified initializer list.

So, there is an invisible = sign there and you can't get around it.

like image 199
Potatoswatter Avatar answered Oct 11 '22 18:10

Potatoswatter