首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这两种表达方式是一样的吗:"CTest CTest(T)“;”CTest cTest=t;“in C++?只是效率不同?

这两种表达方式是一样的吗:"CTest CTest(T)“;”CTest cTest=t;“in C++?只是效率不同?
EN

Stack Overflow用户
提问于 2020-06-06 04:40:47
回答 2查看 53关注 0票数 0

作为研究对象,相关代码被列出,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,我错了吗?我希望能在这个问题上得到一些帮助。

代码语言:javascript
复制
    #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);
    }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-06-06 05:23:42

代码语言:javascript
复制
ClassName var{foo};

这直接调用构造函数,传入foo

代码语言:javascript
复制
ClassName var = foo;

这将尝试将foo隐式转换为ClassName,并要求这种机制是可用的。这可能是ClassName上的非显式转换构造函数,也可能是foo类型上的非显式转换。如果找不到这种隐式转换,则这是编译时错误。

如果可以找到转换:

  • 之前C++17:这将创建一个临时的,然后从它移动构造var,如果可能的话,或者复制构造,如果移动-构造是不可能的。几乎所有编译器都将删除移动/复制,但仍然需要这样的构造函数存在并成为callable.
  • C++17和更高版本:这实际上与显式初始化表单相同。不需要移动/复制构造函数。

我们可以通过一个简单的测试用例来证明这一点:

代码语言:javascript
复制
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模式下编译会产生:

代码语言:javascript
复制
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()

票数 1
EN

Stack Overflow用户

发布于 2020-06-06 05:33:35

我贴出了被quickly.But删除的答案,我认为这是对的。

应该调用用户定义的构造函数EntityId_t(int )和移动赋值操作符。

在概念上,调用构造函数EntityId_t(int )来构造一个临时对象,该对象用于初始化对象;在这种情况下,将使用移动构造函数,但不使用移动赋值操作符。

由于复制省略,最后一步(移动构造函数调用)可能被省略,然后两种方法都会得到相同的效果:对象由构造函数EntityId_t(int )直接初始化。由于C++17复制省略是强制性的,所以在C++17复制省略是优化之前,即使未调用移动构造函数,它也必须是可用的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62227378

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档