Are there any cases where it is incorrect to replace push_back with emplace_back?

前端 未结 6 1420
不思量自难忘°
不思量自难忘° 2021-01-02 09:44

Can I break a valid C++03 program by replacing std::vector::push_back with emplace_back and compiling it with C++ 11 compiler? From reading e

6条回答
  •  被撕碎了的回忆
    2021-01-02 10:16

    Yes, you can change the behavior (more than just avoiding a copy constructor call), since emplace_back only sees imperfectly forwarded arguments.

    #include 
    #include 
    using namespace std;
    
    struct Arg { Arg( int ) {} };
    
    struct S
    {
        S( Arg ) { cout << "S(int)" << endl; }
        S( void* ) { cout << "S(void*)" << endl; }
    };
    
    auto main()
        -> int
    {
        vector().ADD( 0 );
    }
    

    Example builds:

    [H:\dev\test\0011]
    > g++ foo.cpp -D ADD=emplace_back && a
    S(int)
    
    [H:\dev\test\0011]
    > g++ foo.cpp -D ADD=push_back && a
    S(void*)
    
    [H:\dev\test\0011]
    > _
    

    Addendum: as pointed out by Brian Bi in his answer, another difference that can lead to different behavior is that a push_back call involves an implicit conversion to T, which disregards explicit constructors and conversion operators, while emplace_back uses direct initialization, which does consider also explicit constructors and conversion operators.

提交回复
热议问题