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
451 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
7 Replies
Brandon_H_Intel
Employee
451 Views
Hi nthomas99, I can reproduce the errors with the variadic template functions in your code. I've submitted a problem report to our front end team, and I'll let you know what they find.
0 Kudos
Nathan_Thomas
Beginner
451 Views
Great thanks and have a great weekend.
0 Kudos
Nathan_Thomas
Beginner
451 Views
Howdy Brandon, Any update on this? Thanks
0 Kudos
Brandon_H_Intel
Employee
451 Views
Hi Nathan, It looks like our developers have come up with a fix, although it's not clear to me yet whether this will make 13.0. I'm working to find that out.
0 Kudos
Nathan_Thomas
Beginner
451 Views
Thank you for looking into this.
0 Kudos
Nathan_Thomas
Beginner
451 Views
Howdy Brandon, Just to verify, this did not make it into 13.0.1, correct? Thanks.
0 Kudos
Brandon_H_Intel
Employee
451 Views

Hi Nathan,

Sorry for not seeing your earlier pings. I've confirmed the problem is fixed in the 13.1 compiler which is available in Intel(R) C++ Composer XE 2013 update 2. Let me know if that works for you or if you have any problems.

0 Kudos
Reply