This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Base Class initialization with brackets, calls move constructor. Compiles well with parenthesis.


Hello to all.

I have stumbled upon an issue which I honestly do not understand.
The following code example is a reduced example of what I'm trying to
do, and a way to explain the issue.

/*---- Code Starts Here */

#include <iostream>
#include <memory>

using std::cout;
using std::endl;
using std::unique_ptr;


class A_Partial
{
public:
    virtual ~A_Partial(){}

    virtual void WhoAmI() = 0;
};


class A_Complete
: virtual public A_Partial
{
  public:
    virtual ~A_Complete(){}

    template<typename BaseClass, typename ... BaseArgs>
    static
    unique_ptr<A_Complete> CreateObj(BaseArgs&&... args){
        return unique_ptr<A_Complete>(new
BaseClass(std::forward<BaseArgs>(args)...));
    }
};


class O_Partial
: virtual public A_Partial
{
    int x;
    int y;

  protected:
    explicit
    O_Partial(const int& x, const int& y)
    : x{x}, y{y}
    {}

  public:
    O_Partial(const O_Partial&) = delete;
    O_Partial(O_Partial&&) = delete;

    virtual ~O_Partial(){}

    virtual void WhoAmI() {cout << "O_Partial" << endl;}
};


class O_Complete
:
    virtual public A_Complete,
    public O_Partial
{
    template<typename BaseClass, typename ... BaseArgs>
    friend
    unique_ptr<A_Complete> A_Complete::CreateObj(BaseArgs&&... args);

    explicit
    O_Complete(const int& x, const int& y)
    : O_Partial {x, y}
    {}

  public:
    O_Complete() = delete;
    O_Complete(const O_Complete&) = delete;
    O_Complete(O_Complete&&) = delete;

    virtual
    ~O_Complete() {};
};


int main(){
    unique_ptr<A_Complete> ptr = A_Complete::CreateObj<O_Complete>(1,2);
    ptr->WhoAmI();
    return 0;
}

/*---- Code Ends Here */



A_Complete is an abstract class which inherits from A_Partial.
A_Partial contains the methods definitions for a subset of what
A_Complete should have.
For this example, I only added one A_Partial, but for a real-world
example, I could have several A_Partial_x, joining them in the
A_Complete abstract class.

O_Partial implements the A_Partial
O_Complete inherits A_Complete and O_Partial, where in a real-world
example, it would also inherit all existent O_Partial_x, where each
O_Partial_x would implement the respective A_Partial_x abstract class.

Now, in order to instantiate the O_Complete object, the CreateObj
template method from A_Complete must be used.


Now, for the issue.
For some reason that I do not know, in the O_Complete explicit
constructor with two const references for int's, I'm initializing the
O_Partial base class using brackets.

If I use brackets ("O_Partial {x, y}"), the compiler fails by throwing
the following error:

/* Error starts here */

[claymore@claymore-laptop gcc_bug_test]$ g++ -std=c++14 -Wall -Wextra
gcc_move_bug.cpp
gcc_move_bug.cpp: In constructor ‘O_Complete::O_Complete(const int&,
const int&)’:
gcc_move_bug.cpp:73:22: error: ‘O_Partial::O_Partial(const int&, const
int&)’ is protected within this context
     : O_Partial {x, y}
                      ^
gcc_move_bug.cpp:47:5: note: declared protected here
     O_Partial(const int& x, const int& y)
     ^~~~~~~~~
gcc_move_bug.cpp:73:22: error: use of deleted function
‘O_Partial::O_Partial(O_Partial&&)’
     : O_Partial {x, y}
                      ^
gcc_move_bug.cpp:53:5: note: declared here
     O_Partial(O_Partial&&) = delete;
     ^~~~~~~~~
[claymore@claymore-laptop gcc_bug_test]$ g++ -std=c++14 -Wall -Wextra
gcc_move_bug.cpp
gcc_move_bug.cpp: In constructor ‘O_Complete::O_Complete(const int&,
const int&)’:
gcc_move_bug.cpp:69:22: error: ‘O_Partial::O_Partial(const int&, const
int&)’ is protected within this context
     : O_Partial {x, y}
                      ^
gcc_move_bug.cpp:43:5: note: declared protected here
     O_Partial(const int& x, const int& y)
     ^~~~~~~~~
gcc_move_bug.cpp:69:22: error: use of deleted function
‘O_Partial::O_Partial(O_Partial&&)’
     : O_Partial {x, y}
                      ^
gcc_move_bug.cpp:49:5: note: declared here
     O_Partial(O_Partial&&) = delete;
     ^~~~~~~~~

/* Error ends here */


If I use parenthesis instead of brackets ("O_Partial (x, y)"), the
compiler does not complain and everything goes well.

My GCC version is 6.2.1 20160830 (GCC)


Can anyone explain me this issue and help me to understand it?

Thank you!

-- 

Carlos Miguel Ferreira
Researcher at Telecommunications Institute
Aveiro - Portugal
Work E-mail - cmf@av.it.pt
Skype & GTalk -> carlosmf.pt@gmail.com
LinkedIn -> http://www.linkedin.com/in/carlosmferreira


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]