c++namespacesdefault-arguments

Why does `using namespace` interfere with default arguments?


In a minimal project with three files, I have main.cpp

#include "my_class.h"

using namespace foo::bar::baz;

int main()
{
    printDefault();
}

my_class.h:

namespace foo::bar
{
namespace baz
{
    void doDefault(bool actually = false);
    void printDefault();
}
}

and my_class.cpp

#include "my_class.h"

#include <stdio.h>

// using namespace foo::bar;
namespace foo::bar
{
namespace baz
{
void doDefault(bool actually /* = false*/)
{
    actually ? printf("true") : printf("false");
}

void printDefault()
{
    doDefault();
}
} // namespace baz
} // namespace foo::bar

This works fine.

However, if I change my_class.cpp like this:

#include "my_class.h"

#include <stdio.h>

using namespace foo::bar;

namespace baz
{
void doDefault(bool actually /* = false*/)
{
    actually ? printf("true") : printf("false");
}

void printDefault()
{
    doDefault();
}
} // namespace baz

it doesn't compile anymore, because the argument bool actually has no default value anymore. I'd have to call it with an explicit argument. (Calling it with an argument doesn't work either. I mixed something up here before creating the minimal example).

error C2660: 'baz::doDefault': function does not take 0 arguments

Why is that?


Solution

  • using namespace whatever; means that name lookup will look in namespace whatever, but it doesn't mean that any definitions you write automatically define things in namespace whatever.

    If you do

    using namespace foo::bar;
    
    namespace baz
    {
    void doDefault(bool actually /* = false*/)
    {
        actually ? printf("true") : printf("false");
    }
    
    void printDefault()
    {
        doDefault();
    }
    } // namespace baz
    

    then you're defining baz::doDefault and baz::printDefault, not foo::bar::baz::doDefault and foo::bar::baz::printDefault. baz::doDefault doesn't have a default argument value, so trying to call it with 0 arguments is invalid.