作为研究对象,相关代码被列出,below.You可以在https://godbolt.org/z/bcf8js上检查它。
毫无疑问,EntityId_t c_SEDSubscribe(ENTITYID_SEDP_BUILTIN_PUBLICATIONS_READER);调用the user defined constructor EntityId_t(int id),而我认为EntityId_t c_SEDPPubWriter = ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER;应该调用用户定义的构造函数EntityId_t(int id)和移动赋值操作符,但这不是这种情况,因为终止输出。换句话说,我认为ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER调用用户定义的构造函数EntityId_t(int )来生成一个临时object.Since --它是一个rvalue(临时对象),编译器然后调用移动辅助operation.Where,我错了吗?我希望能在这个问题上得到一些帮助。
#include<string.h>
#include<iostream>
#define ENTITYID_UNKNOWN 0x00000000
#define ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER 0x000003c2
#define ENTITYID_SEDP_BUILTIN_PUBLICATIONS_READER 0x000003c1
struct EntityId_t
{
static constexpr unsigned int size = 4;
char value[size];
//! Default constructor. Uknown entity.
EntityId_t(){
*this = ENTITYID_UNKNOWN;
}
EntityId_t(int id)
{
int* aux = (int*)(value);
*aux = id;
std::cout << "EntityId_t(int id) constructor" << std::endl;
}
/*!
* @brief Copy constructor
*/
EntityId_t(
const EntityId_t& id)
{
memcpy(value, id.value, size);
std::cout << "copy constructor" << std::endl;
}
EntityId_t& operator =(
const EntityId_t& id)
{
memcpy(value, id.value, size);
std::cout << "copy operator() constructor" << std::endl;
return *this;
}
/*!
* @brief Move constructor
*/
EntityId_t(
EntityId_t&& id)
{
memmove(value, id.value, size);
std::cout << "move constructor" << std::endl;
}
EntityId_t& operator =(
EntityId_t&& id)
{
memmove(value, id.value, size);
std::cout << "move operator(EntityId_t&&)" << std::endl;
return *this;
}
};
int main()
{
EntityId_t c_SEDPPubWriter = ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER;
std::cout << "==============================" << std::endl;
EntityId_t c_SEDSubscribe(ENTITYID_SEDP_BUILTIN_PUBLICATIONS_READER);
}发布于 2020-06-06 05:23:42
ClassName var{foo};这直接调用构造函数,传入foo。
ClassName var = foo;这将尝试将foo隐式转换为ClassName,并要求这种机制是可用的。这可能是ClassName上的非显式转换构造函数,也可能是foo类型上的非显式转换。如果找不到这种隐式转换,则这是编译时错误。
如果可以找到转换:
在
var,如果可能的话,或者复制构造,如果移动-构造是不可能的。几乎所有编译器都将删除移动/复制,但仍然需要这样的构造函数存在并成为callable.我们可以通过一个简单的测试用例来证明这一点:
class Example {
public:
Example(int) {}
Example(Example const &) = delete;
Example(Example &&) = delete;
};
int main() {
Example b = 0;
(void)b; // Just silencing the unused variable warning
}在C++14模式下编译会产生:
main.cpp: In function 'int main()':
main.cpp:10:17: error: use of deleted function 'Example::Example(Example&&)'
10 | Example b = 0;
| ^在C++17模式下编译成功,表示没有尝试复制或移动构造。
注意,当转换发生时,结果是相同的,因为源值的类型上有一个operator Example()。
发布于 2020-06-06 05:33:35
我贴出了被quickly.But删除的答案,我认为这是对的。
应该调用用户定义的构造函数EntityId_t(int )和移动赋值操作符。
在概念上,调用构造函数EntityId_t(int )来构造一个临时对象,该对象用于初始化对象;在这种情况下,将使用移动构造函数,但不使用移动赋值操作符。
由于复制省略,最后一步(移动构造函数调用)可能被省略,然后两种方法都会得到相同的效果:对象由构造函数EntityId_t(int )直接初始化。由于C++17复制省略是强制性的,所以在C++17复制省略是优化之前,即使未调用移动构造函数,它也必须是可用的。
https://stackoverflow.com/questions/62227378
复制相似问题