0

Consider this program:

#include <iostream>
#include <stack>

class MyStack : public std::stack<double>
{
public:
    void push(char)
    {
        std::cout << "Using char overload of push function.\n";
    }
};

int main()
{
    MyStack stack{};
    stack.push(3.);   // Why does this call push(char)?
}

This program compiles and prints "Using char overload of push function." when run. Why is it so?

I would think that the templated void push( value_type&& value ); would be used because value_type should be double and so should be better fit when calling push with the double argument 3.

I know I can use std::stack as a member and rewrite functions I need from std::stack to MyStack but inheritance with overloading seemed to be more elegant.

Compiler: gcc version 11.2.0 (Ubuntu 11.2.0-19ubuntu1)

Build command: g++-11 -std=c++20 -Wall -pedantic-errors -Wextra -Werror -Wsign-conversion -Weffc++ -o

Lukáš J.
  • 15
  • 5

1 Answers1

0

Answers are in the comments and the dup, this code snippet will give you what you want:

class MyStack : public std::stack<double>
{
public:
    using std::stack<double>::push;

    void push(char c)
    {
        std::cout << "Using char overload of push function\n";
    }
};

And yes, many people (including me) find the way the language is specified to behave in this regard counter-intuitive.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
  • Thank you. I would expect the code in question to just not compile due to the needed conversion. Isn't double to char a narrowing conversion if such a conversion exists at all? – Lukáš J. Dec 14 '22 at 06:21
  • The conversion is certainly legal, but you can force an error by writing `stack.push ({3.});`. Without the braces, neither gcc nor clang issue a warning, even with `-Wall -Wextra`. This is probably for historical reasons. – Paul Sanders Dec 14 '22 at 09:25