c++ - Overload Resolution in a Namespace -


i attempting call overloaded function inside namespace , struggling bit.

working example 1: no namespace

class c {};  inline void overloaded(int) {}  template<typename t> void try_it(t value) {   overloaded(value); }  inline void overloaded(c) {}   int main() {   try_it(1);   c c;   try_it(c);   return 0; } 

working example 2: overloads defined before template

class c {};  namespace n {   inline void overloaded(int) {}   inline void overloaded(c) {} }  template<typename t> void try_it(t value) {   n::overloaded(value); }  int main() {   try_it(1);   c c;   try_it(c);   return 0; } 

broken example 3: overloads after template

class c {};  namespace n {   inline void overloaded(int) {} }  template<typename t> void try_it(t value) {   n::overloaded(value); }  namespace n {   inline void overloaded(c) {} }  int main() {   try_it(1);   c c;   try_it(c); // /tmp/test.cpp: in function ‘void try_it(t) [with t = c]’:              // /tmp/test.cpp:19:15:   instantiated here              // /tmp/test.cpp:8:7: error: cannot convert ‘c’ ‘int’ argument ‘1’ ‘void n::overloaded(int)’    return 0; } 

why case? need able declare or define overload after template function?

this problem of dependent name lookup.

in expression overloaded(value);, name overloaded dependent per [temp.dep]/1.

as far know, in expression n::overloaded(value), name overloaded (in id-expression n::overloaded) not dependent.


dependent name lookup peculiar, [temp.dep.res]/1

in resolving dependent names, names following sources considered:

  • declarations visible @ point of definition of template.
  • declarations namespaces associated types of function arguments both instantiation context , definition context.

(there's point of instantiation function templates @ end of file, declarations associated namespaces can found.)

for non-dependent names, normal lookup rules apply (lookup definition context).

therefore, find names declared after definition of template, have dependent and found via adl.


a simple workaround introduce parameter function overloaded or wrap argument, such 1 of arguments of function has namespace n associated:

#include <iostream>  class c {};  namespace n {   struct adl_helper {};   inline void overloaded(int, adl_helper = {})   { std::cout << "n::overloaded(int,..)" << std::endl; } }  template<typename t> void try_it(t value) {   overloaded(value, n::adl_helper{}); }  namespace n {   inline void overloaded(c, adl_helper = {})   { std::cout << "n::overloaded(c,..)" << std::endl; } }  int main() {   try_it(1);   c c;   try_it(c); } 

alternatively:

namespace n {   template < typename t >   struct wrapper { t elem; };    inline void overloaded(wrapper<int>)   { std::cout << "n::overloaded(wrapper<int>)" << std::endl; } }  template<typename t> void try_it(t value) {   overloaded(n::wrapper<t>{value}); }  namespace n {   inline void overloaded(wrapper<c>)   { std::cout << "n::overloaded(wrapper<c>)" << std::endl; } } 

Comments

Popular posts from this blog

html - How to style widget with post count different than without post count -

How to remove text and logo OR add Overflow on Android ActionBar using AppCompat on API 8? -

javascript - storing input from prompt in array and displaying the array -