相关疑难解决方法(0)

在C++ 14允许的情况下,C++ 17是否禁止复制省略?

考虑以下:

struct X {
    X() {}
    X(X&&) { puts("move"); }
};
X x = X();
Run Code Online (Sandbox Code Playgroud)

在C++ 14中,尽管移动构造函数由于[class.copy]/31而具有副作用,但移动可能会被省略,

在下列情况下允许复制/移动操作的省略...当未绑定到引用(12.2)的临时类对象被复制/移动到具有相同cv-nonqualified的类对象时类型

在C++ 17中,这个子弹被删除了.相反,由于[dcl.init] /17.6.1,保证可以省略此举:

如果初始化表达式是prvalue且源类型的cv-nonqualified版本与目标类相同,则初始化表达式用于初始化目标对象.[ 示例: T x = T(T(T()));调用T默认构造函数进行初始化x.- 结束例子 ]

到目前为止,我所陈述的事实众所周知.但现在让我们更改代码,使其显示为:

X x({});
Run Code Online (Sandbox Code Playgroud)

在C++ 14中,执行重载解析并使用默认构造函数将其{}转换为临时类型X,然后移入x.复制省略规则允许省略此移动.

在C++ 17中,重载决策是相同的,但现在[dcl.init] /17.6.1不适用,并且C++ 14中的子弹不再存在.没有初始化表达式,因为初始化程序是braced-init-list.相反,似乎[dcl.init] /(17.6.2)适用:

否则,如果初始化是直接初始化,或者如果它是复制初始化,其中源类型的cv-nonqualified版本与目标类相同的类或派生类,则考虑构造函数.列举了适用的构造函数(16.3.1.3),并通过重载解析(16.3)选择最佳构造函数.调用所选的构造函数来初始化对象,初始化表达式或表达式列表作为其参数.如果没有构造函数适用,或者重载决策是不明确的,则初始化是错误的.

这似乎需要调用移动构造函数,如果标准中的其他地方有一条规则说可以忽略它,我不知道它在哪里.

c++ language-lawyer copy-elision c++17

12
推荐指数
1
解决办法
439
查看次数

C++转换运算符到chrono :: duration - 适用于c ++ 17但不适用于C++ 14或更低版本

下面的代码使用gcc 7.1.0编译,C++ 17设置,但不使用C++ 14 set(或Visual Studio 2017)编译.它很容易在Wandbox重现.

要使它与C++ 11/14一起使用需要做些什么?

#include <iostream>
#include <chrono>

int main()
{
    struct Convert
    {
        operator std::chrono::milliseconds()
        {
            std::cout << "operator std::chrono::milliseconds" << std::endl;
            return std::chrono::milliseconds(10);
        }

        operator int64_t ()
        {
            std::cout << "operator int64_t" << std::endl;
            return 5;
        }
    };

    Convert convert;

    std::chrono::milliseconds m(convert);
    std::cout << m.count() << std::endl;
    int64_t i(convert);
    std::cout << i << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

c++ conversion-operator c++-chrono c++14 c++17

8
推荐指数
2
解决办法
488
查看次数