Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

bug report: variadic template / function template deduction

Nathan_Thomas
Beginner
315 Views

Howdy All,

As far as I can tell the code below is valid C++11 syntax, and it compiles/runs fine with both gcc and clang.  However, I've tried it with both icc version 12.1.5 and 13.0.0 and get the following error:

nthomas@sanpedro> icc -std=c++0x -o test test.cc
test.cc(64): error: no instance of function template "Proxy<T>::invoke2 [with T=A]" matches the argument list
argument types are: (void (A::*)(int), int)
object type is: Proxy<A>
this->invoke2(&T::foo, x); // error with icc, compiles with gcc & clang
^
detected during instantiation of "void Proxy<T>::foo(int) [with T=A]" at line 76

test.cc(65): error: no instance of function template "Proxy<T>::invoke3 [with T=A]" matches the argument list
argument types are: (void (A::*)(int), int)
object type is: Proxy<A>
this->invoke3(&T::foo, x); // error with icc, compiles with gcc & clang
^
detected during instantiation of "void Proxy<T>::foo(int) [with T=A]" at line 76

Here's the code (I've also attached a file):

#include <iostream>
#include <type_traits>

template<typename T>
struct identity
{
typedef T type;
};


struct A
{
void foo(int x)
{
std::cout << "Hello World " << x << "\n";
}
};


template<typename T>
struct invoker
{
T m_t;

invoker(T& t)
: m_t(t)
{ }

template<typename Class, typename ...Args>
void invoke1(void (Class::* pmf)(Args...), Args... args)
{
(m_t.*pmf)(args...);
}

template<typename Class, typename ...Args>
void invoke2(void (Class::* pmf)(Args...),
typename identity<Args>::type... args)
{
(m_t.*pmf)(args...);
}

template<typename Class, typename ...Args>
void invoke3(void (Class::* pmf)(Args...),
typename std::remove_reference<
typename std::remove_const<Args>::type
>::type const&... args)
{
(m_t.*pmf)(args...);
}
};


template<typename T>
struct Proxy
: public invoker<T>
{
Proxy(T& t)
: invoker<T>(t)
{ }

void foo(int x)
{
this->invoke1(&T::foo, x); // works fine
this->invoke2(&T::foo, x); // error with icc, compiles with gcc & clang
this->invoke3(&T::foo, x); // error with icc, compiles with gcc & clang
}
};


int main()
{

A a;

Proxy<A> b(a);

b.foo(5);
}

===

invoke3(...) is what I have in my codebase.  invoke2(...) is a simplification I'd certainly expect to work here.

Is this a known issue (I know variadics are new in Intel)?  If not, can this please be added as a bug ticket.

Thanks,

--Nathan

0 Kudos
2 Replies
Brandon_H_Intel
Employee
315 Views
Hi nthomas99, This looks like your thread at http://software.intel.com/en-us/forums/topic/327562 got duped here. If this is slightly different, let me know.
0 Kudos
Nathan_Thomas
Beginner
315 Views
this is a dupe. Don't know why it happened or how to delete it :( If you're a moderator, feel free to kill it. Thanks.
0 Kudos
Reply