26

consider the following C++ code.

namespace A {
    void f() { // first function
    }

    void f(int) { // second function
    }
}
...
using A::f; // introduces both functions

Is there a way to introduce only one function?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
MKo
  • 4,768
  • 8
  • 32
  • 35
  • `using` always applies to identifiers, never to specific entities named with them. That's just the way it is. – sbi Aug 16 '11 at 09:21

7 Answers7

21

That behavior is well-defined in the Standard.

C++03 7.3.3 The using declaration:

"...If the name is that of an overloaded member function, then all functions named shall be accessible.".

Eric Z
  • 14,327
  • 7
  • 45
  • 69
8

using keyword will bring all the names into the current scope. So with this current code it's not possible.

However, you can introduce the names partially to the file as following:

namespace A {
  void f();  // declaration
}
using A::f;
// now only `A::f()` is visible in the subsequent code
// technically `A::f(int)` is not yet visible (thus unusable)

// introduce the other function later on
namespace A {
  void f(int);
}

Demo.

Edit: The better way is to put A::f(int) inside a nested namesapce and introduce an alias (for ease of use).

namespace A {
  void f();
  namespace Internal {
    void f(int);
  }
}
using A::f;
namespace A_ = A::Internal;

Now, other function is also usable as A_::f(int).

iammilind
  • 68,093
  • 33
  • 169
  • 336
  • Your demo is flawed -- you call `A::f(int)` before it's declared, so of course it's not found. Here is a fixed version: http://www.ideone.com/2weTx – TonyK Aug 16 '11 at 08:55
  • @iammilind: While the Second method is the right way to go about it, The first method is incorrect, Adopting that method will be a nightmare for code maintainence. It is always better to write simple, lucid code which is understandle easily by the next person to touch it, Such hackery would not fit the bill. – Alok Save Aug 16 '11 at 08:55
3

Not as far as I know. You could write a wrapper function if it is a problem.

void f(int i) { A::f(i); }
Pete
  • 4,784
  • 26
  • 33
2

I will give some more examples in addition to the rest of the answers.

Many books for programming in C++ often expose the whole STD namespace by adding the following line somewhere at the beginning of a source file:

using namespace std;

Exposing the complete namespace actually happens to be a bad practice in real life due to various conflicts that may occur at some point especially when code is supplied by many developers that are working on the same task. Such programming style is also against one of the basic rules of object oriented programming - avoid exposing more than it is actually necessary by encapsulating your data. That is why classes for example have public and private members, getters and setters and so on. Namespaces are just another way to group information. Exposing the whole std namespace is against this rule especially if you want to be using let's say only std::cout, std::cin and std::endl. You can easily apply using to specific functions, which allows you a more precise control and a higher chance of avoiding naming conflicts in the multiple namespaces that you might be using at some point:

using std::cout;
using std::cin;
using std::endl;

This allows you to call cout, cin and endl in your code without the namespace-prefix. If you get a naming conflict at some point it is much, much easier to look at a set of using-directives instead of wondering where in the whole namespace that you have exposed the error comes from.

People also use the using directive for a single function/variable if there is a chain of namespaces or the namespace's name is just too long. If you have something like

namespace my_really_long_and_pointless_namespace_that_does_nothing_at_all {
    void foo() { ... }
}

or

namespace1 {
    namespace2 {
        ...
            namepaceN {
                void foo() { ... }
            }
    }
}

it is a pain in the butt to have to write the whole thing every time you want to call the foo() method. By writing

using my_really_long_and_pointless_namespace_that_does_nothing_at_all::foo;

and respectively

using namespace1::namespace2:: ... ::namespaceN::foo;

you spare your fingers some work.

rbaleksandar
  • 8,713
  • 7
  • 76
  • 161
1

Try doing this:

namespace A { 
    void f() { // first function 
    } }

using A::f; // introduces only above function

namespace A { 

    void f(int) { // second function 
    } 
} 
Ajay
  • 18,086
  • 12
  • 59
  • 105
0

C++ has no mechanism to import one specific function overload from a namespace.

As a workaround you can wrap a function call into a local function:

static inline void f(int i) { A::f(i); }

The keyword static is very important -

  1. It reduces the risk of global namespace pollution to the current compilation unit
  2. It makes it possible to do this in multiple compilation units (and hence can be put in a header file)
  3. It allows the compiler to elide the extra function call (there will be no difference in generated code between calling f() and A::f())
  4. If f is never called, no extra code will be generated
rustyx
  • 80,671
  • 25
  • 200
  • 267
0

It's possible to wrap them in another scope:

namespace B { // Wrap the first function
    void f() { A::f(); }
}

namespace C { // Wrap the second function
    void f(int i) { A::f(i); }
}

int main(int argc, char *argv[])
{
    {
        using B::f; // Make the first function available
        f();
    } // Make the first function unavailable

    {
        using C::f; // Make the second function available
        f(0);
    } // Make the second function unavailable

    return 0;
}

But I don't think you can do that with a single using declaration.

Seb Holzapfel
  • 3,793
  • 1
  • 19
  • 22