请考虑以下代码:
#include <iostream>
#include <type_traits>
struct type {};
int main(int argc, char* argv[]) {
std::cout << std::is_convertible_v<volatile int, int> << " ";
std::cout << std::is_convertible_v<volatile int, volatile int> << " ";
std::cout << std::is_convertible_v<volatile type, type> << " ";
std::cout << std::is_convertible_v<volatile type, volatile type> << std::endl;
return 0;
}
打印出来
1 1 0 0
为什么volatile int
可以转换为int
,而volatile type
不能转换为type
? 为什么易失性类型
甚至不能转换为易失性类型
?
有没有方法使volatile
类可复制?
注意:欢迎引用C++标准
type
隐式声明的默认构造函数具有此签名
type::type(type const&);
引用不能绑定到volatile对象,因为那样会丢弃限定符。
[class.copy.ctor]
7类x
隐式声明的复制构造函数的形式为
X::X(const X&)
如果类类型M(或其数组)的每个潜在构造的子对象都有一个复制构造函数,其第一个参数为const M&;
或const volatile M&;
类型。 否则,隐式声明的复制构造函数将具有
X::X(X&)
无论哪种方式,编译器都不会隐式声明一个接受volatile对象引用的构造函数。
转换中的目标对象是易失性的这一事实也没有什么区别。 这样的转换需要一个能够绑定到易失性源的复制构造函数。
基本类型不会被构造函数复制,因此这种行为不会限制它们。
有没有方法使volatile
类可复制?
如果需要,则需要用户声明复制构造函数,该构造函数接受对const volatile
对象的引用。
这种到相同类型(忽略限定符)的转换是复制/移动。
type
具有隐式生成的复制和移动构造函数,该构造函数接受对非易失性限定对象的引用。 此类引用不能绑定到volatile参数,因此不允许从volatile进行转换。
没有隐式生成的构造函数接受对volatile限定对象的引用。 (类似地,没有隐式volatile限定赋值运算符,也没有带有volatile限定参数的赋值运算符)。
这是C++与允许复制volatile结构的有效C不兼容的方式之一。
有没有一种方法可以让一个易失性的类成为可复制的呢?
您可以从技术上定义允许它的构造函数:
struct type {
type() = default;
type(type const & ) = default;
type(type &&) = default;
type(type volatile const & ) {}
type(type volatile &&) {}
};
根据您期望volatile的行为方式(volatile对象的访问是在实现中定义的),可能不一定有一种方法来实现这个构造函数,而如果存在多个子对象,则可以期望从volatile对象中进行复制。
Volatile类对象通常不太有用,在我看来最好避免使用。