C++ Riddle - Feb-08, 2022

The following code uses some existing class A, which is defined somewhere.
An A object can be constructed without any parameters, as can be seen at the first line in main.
An A object can be constructed from another A, as can be seen at the second line in main.
We can create an std::vector of A, as can be seen at line number three in main.
But we cannot push_back items of type A into the vector for some reason…

What may have been done wrong in A that created this damn shame?

int main() {
    A a1; // ok
    A a2 = a1; // ok
    std::vector<A> vec; // ok
    vec.push_back(a1); // compilation error
    vec.push_back(a2); // compilation error
    vec.push_back(A{}); // compilation error
}
3 Likes

Did A disable some of the ctors ?

if class A has a deleted move constructor. The reason for that is it is marked as deleted so it is still the better constructor match option and since it is deleted the compiler will not compile

If you have a deleted the move ctor, then line #2 in the main would also fail, because the copy ctor is implicitly deleted.

A a2 = a1; // this line would fail as well

No, at least not in a “normal” way.
If for example the copy ctor is disabled then line #2 would also fail, and it passes:

A a2 = a1; // ok

but did you =default it to bring it back?
BTW - could it be something related to access specifiers?

1 Like

Try to write it.

You may achieve the behavior above with more than a single option. However, the actual case that brought me to present this riddle, is a very simple and nice kind-of-a bug (well, it is not a bug per-se, but the programmer did something not according to the best practice).

Hint:
class A has two user declared constructors, both are declared with = default.
There are no other user declared or user defined, nor explicitly deleted, constructors or destructor.

Sorry you are right you have to have copy constructor and default constructor implemented. as long as delete the move constructor.

Avi, your code passes two lines that are marked as “compilation error”:

int main() {
    A a1; // ok
    A a2 = a1; // ok
    std::vector<A> vec; // ok
    vec.push_back(a1); // in the question compilation error - in your code passes
    vec.push_back(a2); // in the question compilation error - in your code passes
    vec.push_back(A{}); // compilation error - in both
}

@kobica @avilachmish and all other puzzlers:

  • all members in the class are public
  • there are only two members in the class
  • both are constructors
  • both declared with =default
  • nothing else
  • it’s not an example of good code, but it may actually happen for a novice

std::vector push_back requires a class T to be CopyInsertable or MoveInsertable.

class f {
public:
f(f&) = default;
}

std::is_copy_constructible::value is false

there for having defualt constructor and copy constructor not defined with const variable does not make it niether CopyInsertable or MoveInsertable and there for will fail to push_back

1 Like

@avilachmish Yes, that’s it:

class A {
public:
   A() = default;
   A(A&) = default; // oops, oh boy, forgot the const
};

The riddle was inspired by this SO question:

1 Like