4

I would like to know, when someone gives you a template for a default constructor in C++ and in the parameter there is a series of unnamed variables that somehow are assigned values. What does this mean? Is this legal? How can one access these variables?

Example I received:

IntSet::IntSet(int = -1, int = -1, int = -1, int = -1); //default constructor

I would appreciate any answers that clarify this use!

Eamon Bohan
  • 522
  • 2
  • 8
  • 22

2 Answers2

6

It's perfectly legal to not name the arguments in the declaration or in the definition of a function. It's also perfectly legal to use different names for a given argument in the declaration and definition.

Note that if a parameter that is not named in the definition is not accessible. Why do this? A lot of compilers can be made to complain about unused arguments. Most compilers won't complain if the function definition doesn't name those unused arguments.

About unnamed parameters in a declaration, which is the topic of this question: Just because doing this is legal doesn't necessarily mean it's a good practice. Those unnamed arguments in a function declaration might be fine for a compiler, but they aren't fine for a human reader. No name = zero communication. The documentation and header file should contain everything that an external user needs to know regarding how to use the class. RTFM and maybe RTFH (read the fine manual / read the fine headers). That "F" word ("fine") in RTFM and RTFH takes on a different meaning in RTFC.

Those unnamed arguments in a header are almost inevitably coupled with poor documentation. As an external user, this forces me to read the function's definition to understand how to use a function. RTFC. It is not fine when an external user has to read the implementation to determine what is going on.

David Hammen
  • 32,454
  • 9
  • 60
  • 108
1

That means that if you call it without passing parameters, the parameters will take the values you passed.

So if you call

IntSet* i = new Intset();

would be equivalent to calling

Intset* i = new IntSet(-1,-1,-1,-1)

About the unnamed part. I would assume because it is part of a library that uses templates. The nameless parameters are not used, but are there so it matches the signature of another class that may need them. In the case that it needs them, it will just pass -1 by default. You can take a look at this link for an example:

http://compgroups.net/comp.lang.c++/unnamed-formal-parameter/1004784

I am copying the example from the above reference here, to make the case for using such a construct in an useful way

For instance

class A
{
     public:
     A(void* = 0) {}    // unused parameter
};

class B
{
    public:
    B(void* p) : pp(p) {} // used parameter
private:
    void* pp;
};

template <class T>
class C
{
public:
    static T* create(void* p = 0) { return new T(p); }
};

int main()
{
    A* a = C<A>::create();
    B* b = C<B>::create("hello");
}

C::create would not compile unless A::A had a parameter even though it is not used.

cloudraven
  • 2,484
  • 1
  • 24
  • 49
  • 1
    The parameters can be unnamed in the declaration and still used in the definition if they are named in the definition. There's nothing in the standard that says that the parameter names (if any) have to match between declaration and definition. All that has to match is the signature and the return type. – David Hammen Oct 13 '12 at 23:38
  • True that. I never said the names have to match, sorry if I seemed to imply otherwise. I meant match the type and quantity of parameters of another template class as the example in the reference shows – cloudraven Oct 14 '12 at 02:42
  • I know this is old but why if I removed the whitespace from A(void*=0) the compiller thrown an error? I knew that whitespaces doesn't matter. – user3134909 Mar 13 '18 at 23:54