C++ 是C++;17复制省略适用于新放置?

C++ 是C++;17复制省略适用于新放置?,c++,c++17,C++,C++17,我正在为脚本语言编写一个通用接口,需要调用函数返回一个对象,并将结果对象放入脚本语言提供的空间中。 我已经在Mac OS上使用clang++进行了测试,以下内容似乎可以实现复制/移动省略: class T { public: T() {} T(const T &t) { std::cout << "Copy" << std::endl; } T(T&&t) : x(t.x) { std

我正在为脚本语言编写一个通用接口,需要调用函数返回一个对象,并将结果对象放入脚本语言提供的空间中。 我已经在Mac OS上使用clang++进行了测试,以下内容似乎可以实现复制/移动省略:

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);
}
我认为我的代码非常类似于没有复制省略的情况下,会调用move构造函数(就像
T(T(f())
会调用两个move构造一样)

作为一名规范律师,我很好奇我的理解是否正确,我想知道是否所有支持C++17的编译器都能正确地做到这一点?

保证省略(aka:C)适用于任何类型为
T
且具有相同类型PR值的对象的初始化。包括由
new
表达式创建的对象,包括放置
new
表单


实际上,您甚至不必在调用
new
表达式时重复该类型:
new(p)auto(h())
确保保证省略的必要条件。

仅供参考:不要放弃
新表达式的返回值;你应该使用它,而不是将
空格
转换成
T*
@nicolabolas你是对的,但直到我读了你的答案,我才明白你的意思,也不知道怎么做。我想问你更多的信息。这是我第一次看到构造函数的auto语法。您是否测试过其他编译器是否正确执行此操作?我读到一些较旧的Visual Studio版本没有正确地执行复制省略。@米歇尔:自从C++11中引入了
auto
reduction以来,语法一直是合法的。在C++17之前,给定的对象是从中移动还是就地构造是由编译器决定的。既然您在问题中使用了“C++17”标记,那么谈论符合C++17之前版本的编译器的行为就有点无关紧要了。
T x = T(T(f())); // only one call to default constructor of T, to initialize x