Czy elision / przyporządkowanie domyślnego konstruktora jest możliwe w zasadzie?

. lub nawet dozwolone przez standard C ++ 11?

A jeśli tak, to czy istnieje jakiś kompilator, który rzeczywiście to robi?

Oto przykład tego, co mam na myśli:

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

Odnośnie zaznaczonej linii:
Czy wartości x + y, x * y, x * x, y * y można zapisać bezpośrednio w pamięci d? Czy może zwracać typ get_data bezpośrednio w pamięci d?
Nie mogę wymyślić powodu, aby nie pozwolić na taką optymalizację. Przynajmniej nie dla klasy, która ma tylko konstruktory constexpr i domyślne operatory kopiowania i przypisania.

g ++ 4.7.2 usuwa wszystkie konstruktory kopii w tym przykładzie; wydaje się jednak, że przypisanie jest zawsze wykonywane (nawet tylko w przypadku domyślnego przypisania - o ile wiem z zespołu, który emituje g ++).

Motywacją dla mojego pytania jest następująca sytuacja, w której taka optymalizacja znacznie uprościłaby i poprawiła projektowanie biblioteki. Załóżmy, że piszesz procedury biblioteczne o krytycznym znaczeniu dla wydajności, używając klasy literalnej. Obiekty tej klasy będą posiadać wystarczającą ilość danych (powiedzmy 20 podwójnych), że kopie muszą być ograniczone do minimum.

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

Pozwoliłoby to na znacznie czystszy (styl programowania funkcjonalnego) projekt, gdybym mógł zrezygnować z drugiej funkcji. Ale czasami muszę tylko zmodyfikować długotrwały obiekt dosłowny i upewnić się, że nie utworzę nowego obiektu i skopiować go do tego, który chcę zmodyfikować. Sama modyfikacja jest tania, kopie nie - tak wskazują moje eksperymenty.

EDYTOWAĆ:
Załóżmy, że optymalizacja będzie dozwolona tylko dla klasy z konstruktorami constexpr noexcept i operatorem domyślnym noexcept =.

questionAnswers(4)

yourAnswerToTheQuestion