¿Es posible, en principio, la elección del constructor por defecto?

. ¿O incluso permitido por el estándar C ++ 11?

Y si es así, ¿hay algún compilador que realmente lo haga?

Aquí hay un ejemplo de lo que quiero decir:

template<class T> //T is a builtin type
class data 
{
public:
    constexpr
    data() noexcept :
        x_{0,0,0,0}
    {}

    constexpr
    data(const T& a, const T& b, const T& c, const T& d) noexcept :
        x_{a,b,c,d}
    {}

    data(const data&) noexcept = default;

    data& operator = (const data&) noexcept = default;

    constexpr const T&
    operator[] (std::size_t i) const noexcept {
        return x_[i];
    }

    T&
    operator[] (std::size_t i) noexcept {
        return x_[i];
    }

private:
    T x_[4];
};


template<class Ostream, class T>
Ostream& operator << (Ostream& os, const data<T>& d)
{
    return (os << d[0] <<' '<< d[1] <<' '<< d[2] <<' '<< d[3]);
}


template<class T>
inline constexpr
data<T>
get_data(const T& x, const T& y)
{
    return data<T>{x + y, x * y, x*x, y*y};
}


int main()
{
    double x, y;
    std::cin >> x >> y;

    auto d = data<double>{x, y, 2*x, 2*y};

    std::cout << d << std::endl;

    //THE QUESTION IS ABOUT THIS LINE
    d = get_data(x,y);  

    d[0] += d[2];
    d[1] += d[3];
    d[2] *= d[3];

    std::cout << d << std::endl;

    return 0;
}

Respecto a la línea marcada:
¿Se podrían escribir los valores x + y, x * y, x * x, y * y directamente en la memoria de d? ¿O podría el tipo de retorno de get_data ser construido directamente en la memoria de d?
No puedo pensar en una razón para no permitir tal optimización. Al menos no para una clase que solo tiene constructores constexpr y operadores de copia y asignación predeterminados.

g ++ 4.7.2 elimina todos los constructores de copia en este ejemplo; Sin embargo, parece que la asignación siempre se realiza (incluso solo para la asignación predeterminada, por lo que puedo decir del ensamblaje que emita g ++).

La motivación para mi pregunta es la siguiente situación en la que tal optimización simplificaría y mejoraría enormemente el diseño de la biblioteca. Supongamos que escribe rutinas de biblioteca críticas para el rendimiento utilizando una clase literal. Los objetos de esa clase contendrán datos suficientes (por ejemplo, 20 dobles) que las copias deben reducirse al mínimo.

class Literal{ constexpr Literal(...): {...} {} ...};

//nice: allows RVO and is guaranteed to not have any side effects
constexpr Literal get_random_literal(RandomEngine&) {return Literal{....}; }

//not favorable in my opinion: possible non-obvious side-effects, code duplication
//would be superfluous if said optimization were performed
void set_literal_random(RandomEngine&, Literal&) {...}

Sería un diseño mucho más limpio (estilo de programación funcional) si pudiera prescindir de la segunda función. Pero a veces solo necesito modificar un objeto Literal de larga duración y tengo que asegurarme de no crear uno nuevo y copiarlo y asignarlo al que quiero modificar. La modificación en sí es barata, las copias no lo son, eso es lo que indican mis experimentos.

EDITAR:
Supongamos que la optimización solo se permitirá para una clase con los constructores noexcept constexpr y el operador predeterminado noexcept =.

Respuestas a la pregunta(4)

Su respuesta a la pregunta