I am writing a generic interface for scripting languages and need to call functions that return an object and put the resulting object in a space provided by the scripting language. I have tested with clang++ on Mac OS and the following seems to do the copy/move elision:
class T {
public:
T() {}
T(const T &t) {
std::cout << "Copy" << std::endl;
}
T(T&&t) : x(t.x) {
std::cout << "Move" << std::endl;
}
private:
int x = 3;
};
T h()
{
return T();
}
void buildTInto(void *p)
{
new (p) T(h());
}
int main(int argc, char *argv[])
{
alignas(T) char space[sizeof(T)];
buildTInto(space);
}
Running this code does not print anything. Reading the cpp reference description of copy elision seems to indicate this is the correct behavior, given the example they give which only calls one constructor:
T x = T(T(f())); // only one call to default constructor of T, to initialize x
I think my code is very much similar as without copy elision, the move constructor would be called (just like the T(T(f()))
would call two move construction).
Not being a spec lawyer, I am curious if my understanding is correct and I wonder if all C++17 capable compilers do this correctly?