-1

I have questions about std::stack Why these two constructors are explicit ?

     explicit stack( const Container& cont = Container() );
     explicit stack( Container&& cont = Container() );

Note: Source

eerorika
  • 232,697
  • 12
  • 197
  • 326
Laith
  • 1,248
  • 2
  • 11
  • 19
  • 1
    I don't get your 3. (http://en.cppreference.com/w/cpp/container/stack/operator%3D)? – Holt Jun 29 '16 at 14:27
  • 3
    One question per question, please. – eerorika Jun 29 '16 at 14:27
  • 3
    (1): [Possible duplicate](http://stackoverflow.com/questions/102459/why-does-stdstack-use-stddeque-by-default?rq=1) – sjrowlinson Jun 29 '16 at 14:28
  • Why don't you just ask question 2 so we do not have to close this as a duplicate of: http://stackoverflow.com/questions/102459/why-does-stdstack-use-stddeque-by-default?rq=1 – NathanOliver Jun 29 '16 at 14:29
  • I edited the post ... didnt see operator= – Laith Jun 29 '16 at 14:29
  • 10
    So they don't get invoked implicitly, of course. –  Jun 29 '16 at 14:33
  • You wouldn't want a function expecting a `const std::stack&` to accept an `std::vector` and create a temporary copy every time. The `explicit` is there to warn the caller that they should probably handle the conversion, either with an explicit cast or by creating an `std::stack` – KABoissonneault Jun 29 '16 at 14:48
  • @Hurkyl surely the more interesting interpretation of the question is "why should implicit construction from these constructors be avoided". – eerorika Jun 29 '16 at 14:50

2 Answers2

4

The constructors are explicit so you can't accidentally pass an underlying container (such as vector or deque) to a function expecting a stack, resulting in unexpected copying (not to mention violating the principle of least surprise).

Mark B
  • 95,107
  • 10
  • 109
  • 188
0

One problem is that if you assume implicit invocation, what would happen if others followed your example? So for instance the following fails to compile

#include <iostream>
#include <vector>
using namespace std;

class Test {
  public:

    Test(const std::vector<int>&) {
        cout << "Test(const std::Vector<int>&)" << endl;
    }
};
class AnotherTest {
  public:

    AnotherTest(const std::vector<int>&) {
        cout << "AnotherTest(const std::Vector<int>&)" << endl;
    }
};

void test_function(const AnotherTest&) {
    cout << "fucntion(const AnotherTest&)" << endl;
}
void test_function(const Test&) {
    cout << "fucntion(const Test&)" << endl;
}

int main() {
    const std::vector<int> vec {1, 2, 3};
    test_function(vec);

    return 0;
}

You can easily see this problem occurring with a stack and a queue.

Curious
  • 20,870
  • 8
  • 61
  • 146