How to pass a default parameter for std::shared_ptr<PureVirtualClass>
Asked Answered
N

3

13

I have a function of type

virtual void foo(bla, bla, bla, std::shared_ptr<LoggerInterface> logger) = 0;

And I want to pass a default parameter with NULL pointer, something like:

virtual void foo(bla, bla, bla, std::shared_ptr<LoggerInterface> logger = NULL) = 0;

So that in implementation, if logger is NULL I do nothing with it, otherwise I use the logger.

I've tried to look for a solution but cannot find..

UPD: Duplicate claim is irrelevant, I am asking about default NULL parameter.

Is it possible that gcc 4.4 doesn't support nullptr?

Nuptial answered 29/12, 2016 at 14:41 Comment(4)
You should use nullptr instead of NULL. The latter is a macro that is likely 0, the former is the proper literal for a null pointer.Quartersaw
I've tried but also get compilation error: error: ‘nullptr’ was not declared in this scopeNuptial
This question isn't a duplicate of "Can virtual functions have default parameters". The fact that the function is virtual is irrelevant to this question.Anglicist
@EricAbramov on linux u have to add -std=c++11Anodize
C
9

You can simply do this:

virtual void foo(bla, bla, bla, std::shared_ptr<LoggerInterface> logger = {}) = 0;

As you can see here, both the empty constructor and nullptr give the same result, that is:

Constructs a shared_ptr with no managed object, i.e. empty shared_ptr

Chest answered 29/12, 2016 at 23:7 Comment(0)
V
3

With a C++11 compliant compiler

This should work with either NULL or nullptr the latter being the recommended form for C++. The only condition is that you compile it for c++11 or higher (see comment of jamek about the command line options for gcc).

struct B {
    virtual void foo(int blablabla, std::shared_ptr<LoggerInterface> logger = nullptr) = 0;
};

struct D : B {
    void foo(int blablabla, std::shared_ptr<LoggerInterface> logger) override {
        std::cout << "foo: "<<blablabla<<" "<< logger<<std::endl; 
    }
};

int main() {
    D d; 
    B *b=&d;
    b->foo(15); 
}

See online demo

Important remark about default parameters

Note that the default parameter is not intrinsic to the function itself, but to the context in which the default value was declared. In the example above:

  • b->foo(15) works, because the function is accessed using the B class for which a default parameter is defined.
  • d.foo(15) won't even compile, despite both referring to the same function. This is because for the D class I didn't declare a default value in the definition of the override.
  • I could even have a different default value for both definitions (see in the online demo)

Limitated implementation of C++11 in GCC 4.4

Indeed, nullptr was introduced with GCC 4.6 and you have to wait GCC 4.8.1 for a full C++11 implementation.

In fact GCC 4.4.0 was released in 2009 and the first sub-release after the official approval of the standard in august 2011 was GCC 4.4.7.

Violation answered 29/12, 2016 at 16:9 Comment(4)
thanks, but the issue is that gcc 4.4 doesn't support all c++11 features like nullptrNuptial
Indeed: nullptr was introduced only with 4.6 !Violation
@EricAbramov and And 4.4.0 dates back to 2009, and 4.4.7 was the first release after the official approval of c++11Violation
Yeah, I should wait until the production pipeline in my company will be upgraded to gcc 4.6Nuptial
D
0

IMHO, if you are looking to pass a null pointer, then do not use shared_ptr as the argument type. Instead use a raw pointer. This way, you don't have to figure out the arcane default value for a shared pointer.

And you can keep the benefits of shared_ptr by passing the embedded raw pointer. In your case, it looks like below.

// In declaration file
virtual void foo(bla, bla, bla, LoggerInterface* logger = nullptr) = 0;


std::shared_ptr<LoggerInterface> loggerPtr(new LoggerInterface());
// or
std::shared_ptr<LoggerInterface> loggerPtr;

// Call the function
Bar bar;
bar.foo(bla, bla, bla, loggerPtr ? loggerPtr.get() : nullptr);
...


Deathday answered 23/2, 2020 at 10:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.