4

When I try to build this code:

// foo.h
namespace foo {
    namespace bar {
        void put();
    }
}
#include "foo.h"
namespace foo {
    namespace {
        template<typename T>
        void put() { }
    }    
    void bar::put() {
        put<int>();
    };
}

I get the error:

foo.cpp: In function ‘void foo::bar::put()’:
foo.cpp: error: expected primary-expression before ‘int’
foo.cpp: error: expected ‘;’ before ‘int’

Clearly, put<int> is using put to refer to bar::put. How can I make it refer to the put<T> in the anonymous namespace?

nneonneo
  • 154,210
  • 32
  • 267
  • 343
Eric
  • 87,154
  • 48
  • 211
  • 332

1 Answers1

4

You could fully qualify the function template's name:

namespace foo {
    namespace bar {
        void put();
    }
}

namespace foo {
    namespace {
        template<typename T>
        void put() { }
    }
    void bar::put() {
        ::foo::put<int>();
    }
}

Also notice, that you don't need to use the semi-colon after a function definition.

Andy Prowl
  • 114,596
  • 21
  • 355
  • 432
  • Does it have to be `::foo::put`? `foo::put` seems to work as well, although I'm not sure whether that's just the compiler being lenient about things. – us2012 Feb 28 '13 at 14:09
  • Semicolon was left over from narrowing down the problem. Whoops. – Eric Feb 28 '13 at 14:10
  • or `foo::template put();` or `foo::put();` – justin Feb 28 '13 at 14:10
  • Any way that I can avoid mentioning `foo` to qualify the name? – Eric Feb 28 '13 at 14:11
  • 2
    @us2012: I think `foo::put` is enough in this case, but `::foo::put` is safer in case namespace `foo` contains another namespace called `foo` (maybe not the case here, still...) – Andy Prowl Feb 28 '13 at 14:11
  • @Eric: I don't think so. Not as long as both the function and the function template are called `put()`. – Andy Prowl Feb 28 '13 at 14:16
  • So declaring it as `void bar::put() {}` is not treated differently to `namespace bar { void put() {} }`? In the latter, it's obvious that `put` refers to `bar::put`, but I was expecting the former to have different resolution rules. – Eric Feb 28 '13 at 14:20
  • @Eric: Yes, I believe they are treated the same. They are alternative definitions of the exact same function after all, it makes sense that name resolution rules don't change. – Andy Prowl Feb 28 '13 at 14:22