no ADL / Koenig lookup for function calls with template parameters

C

cgv

Hi,

I want to distinguish between an int parameter to a template function
depending on whether its value is known at compile time or not. For the
compile time version I want to call the function with the syntax

func<5>();

and for the dynamic version with

func(5);

This can be simply achieved by function overloading through the two function
declarations:

template <int i> void func() { ... }
void func(int i) {... }

The same thing I want to combine with argument dependent lookup (ADL).
Therefore the functions are declared inside a namespace for example "test"
and both get an argument of a templated typename T:

namespace test {
template <int i, typename T> void func(const T&) {...}
template <typename T> void func(int i, const T&) {...}
}

If we now declare a struct A inside the same namespace:

namespace test {
struct A { ... };
}

ADL should allow us to use func on an instance of A in the main function
without specifying the namespace test:

void main(int,char**) {
test::A a;
func<2>(a); // error under visual studio 8 (.Net 2005)
func(2,a); // this is fine
}

In this code the ADL does not work for the compile time version, where the
int is passed as template argument. Now my questions:

1. Is this a bug of the Visual Studio 8 compiler or is this use of ADL not
intended by the standard?

2. Has anyone a good idea of circumvent this problem without messing up the
notation too much?

In order to let you try this out on other compilers here is a complete
example:

#include <iostream>

namespace test

{

template <int i, typename T>

void func_a(const T& t)

{

std::cout << "called func with t = " << t << " and i = " << i <<
std::endl;

}

template <typename T>

void func_b(int i, const T& t)

{

std::cout << "called func with t = " << t << " and i = " << i <<
std::endl;

}

struct A

{

int i;

A(int _i) : i(_i) {}

friend std::eek:stream& operator << (std::eek:stream& os, const A& a)

{

return os << a.i;

}

};

}

void main(int, char**)

{

test::A a(3);

func_a<1>(a); // error

func_a<1,test::A>(a); // error

test::func_a<1>(a); // this is fine but does not help

func_b(1, a); // this works perfect

}
 
K

kwikius

cgv said:
1. Is this a bug of the Visual Studio 8 compiler or is this use of ADL not
intended by the standard?

VC8 is correct. I would say that rather than not intended its a
problem.
The compiler doesnt know what func is outside its namespace , so it
might be a variable as it parses it e.g:

func < 2

etc.
2. Has anyone a good idea of circumvent this problem without messing up the
notation too much?

One option is to provide a type:
#include <iostream>
namespace my{

template <int N> struct dummy_int{};

}

//Now use :
namespace my{

template <int N>
void func( dummy_int<N>)
{
std::cout << " N = " << N << '\n';
}

}

int main()
{
func(my::dummy_int<2>());
func(my::dummy_int<1000>());
}

regards
Andy Little
 
?

=?ISO-8859-15?Q?Jens_M=FCller?=

cgv said:
In order to let you try this out on other compilers here is a complete
example:
[...]

void main(int, char**)

int main (int, char**)

[...]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top