Default arguments in constructor

Hi all,

I'm using default arguments in a non-default ctor to mimic the default ctor:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef MYCLOCK_HPP
#define MYCLOCK_HPP

#include <iostream>

class MyClock {
public:
    using uint = unsigned int;

    MyClock() = delete;
    MyClock(const uint _minutes = 0, const uint _seconds = 0);

private:
    uint minutes,
         seconds;
         
}; // END MyClock

MyClock::MyClock(const uint _minutes, const uint _seconds) : minutes(_minutes), seconds(_seconds) {
    std::cout << "Ctor\n";
} // END MyClock(minutes, seconds)

#endif 


With this driver/compilation:
g++ -std=c++14 -pedantic -Wall -Wextra -Wpedantic
1
2
3
4
5
6
7
8
9
10
11
#include "MyClock.hpp"

int main( /* int argc, char** argv */ ) {
    MyClock x(10, 30);
    MyClock y(1, 3);
    MyClock z();
    
    std::cout << x << " " << y << " " << z << '\n';

return 0;
} // END main() 


I'm getting this output:
Ctor
Ctor
10m 30s 1m 3s 1


What ctor is z using? I thought I deleted the default/compiler generated one?

Update: Left out g++ warning:
main.cpp:  In function 'int main()':
main.cpp:13:41: warning: the address of 'MyClock z()' will always evaluate as 'true' [-Waddress]
    cout << x << " " << y << " " << z << '\n';
                                    ^

Obviously (I think) the 1 in the program output is from this but... I don't understand what's going on here.
Last edited on
This line: MyClock z();
Is not a declaration of a variable named z, but rather a declaration of a function returning an instance of MyClass and accepting no parameters.

Use the uniform initialization syntax (preferably everywhere),
MyClock z{}
or omit the parentheses.
MyClock z;
Last edited on
If I do it either of those ways it seems like it tries to call the default ctor which has been deleted.

main.cpp: In function ‘int main()’:
main.cpp:7:13: error: call of overloaded ‘MyClock()’ is ambiguous
     MyClock z;
             ^
In file included from main.cpp:2:0:
MyClock.hpp:38:1: note: candidate: MyClock::MyClock(MyClock::uint, MyClock::uint)
 MyClock::MyClock(const uint _minutes, const uint _seconds) : minutes(_minutes), seconds(_seconds)
 ^
MyClock.hpp:10:5: note: candidate: MyClock::MyClock() <deleted>
     MyClock() = delete;
Oh, sorry.

Do not explicitly delete the default constructor (w/o default arguments). On line 10.
Last edited on
So with the default arguments in MyClock(const uint _minutes = 0, const uint _seconds = 0); the compiler generates a default constructor? I ask because if I do this:
1
2
// MyClock() = delete;
MyClock(const uint _minutes, const uint _seconds);

It wont compile (no matching function call for MyClock z{})
A default constructor is a constructor with no arguments, or a constructor with default arguments provided for every parameter.
MyClock(const uint _minutes = 0, const uint _seconds = 0);
Is a default constructor itself.

A default constructor is generated when
a.) you explicitly default it; or
b.) you haven't defined any constructors.
It will not be generated when
a.) you've explicitly deleted it;
b.) you've written it yourself; or
c.) you have defined at least one non-default constructor. (Unless you also explicitly default the default constructor)

Last edited on
Topic archived. No new replies allowed.