Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why can't the using keyword be used for a forward declaration when defining a function?

Given the following header and source, in which a simple function GiveMeATwo is forward declared in the header test.hpp, within the namespace SomeNamespace, why does a conflict occur when trying to bring the function GiveMeATwo into scope via using SomeNamespace::GiveMeATwo, prior to defining GiveMeATwo?

test.hpp

#ifndef _TEST_HEADER_
#define _TEST_HEADER_

namespace SomeNamespace {
    int GiveMeATwo();
}

#endif

test.cpp

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

#include "test.hpp"

using SomeNamespace::GiveMeATwo;

int GiveMeATwo() {
    return 2;
}

Compiling with Apple clang version 14.0.0 (clang-1400.0.29.202) yields the following error, indicating that the using statement somehow implicitly introduces a declaration?

test.cpp:5:5: error: declaration conflicts with target of using declaration already in scope
int GiveMeATwo() {
    ^
./test.hpp:6:5: note: target of using declaration
int GiveMeATwo();
    ^
test.cpp:3:22: note: using declaration
using SomeNamespace::GiveMeATwo;
                     ^
1 error generated.

Furthermore, what is the difference between bringing the GiveMeATwo symbol into scope via using namespace SomeNamespace, versus using SomeNamespace::GiveMeATwo as I have done here?

>Solution :

To quote cppreference:

If an entity is declared, but not defined in some inner namespace, and then declared through using-declaration in the outer namespace, and then a definition appears in the outer namespace with the same unqualified name, that definition is a member of the outer namespace and conflicts with the using-declaration

In other words, this definition:

int GiveMeATwo() {
    return 2;
}

is for another function. If you want to define the one in SomeNamespace, you still need to name the namespace, even if you wrote using SomeNamespace::GiveMeATwo; or using namespace SomeNamespace; before it:

int SomeNamespace::GiveMeATwo() {
    return 2;
}

Demo

The using-directive (using namespace) is slightly different because:

Using-directive does not add any names to the declarative region in which it appears (unlike the using-declaration), and thus does not prevent identical names from being declared.

So you can do this:

namespace SomeNamespace {
    int GiveMeATwo();
}

using namespace SomeNamespace;

int GiveMeATwo() {
    return 2;
}

but it’s somewhat useless because a call to GiveMeATwo is now ambiguous unless you qualify it, like ::GiveMeATwo(); for the outer function or SomeNamespace::GiveMeATwo(); for the inner one.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading