Search code examples
c++templatesc++11friendicc

Friend function default template : Intel ICPC warning


I have the following test code :

// friendfunction.h                                                                                   
#include <iostream>

template<typename T, unsigned int... TDIM> class MyClass
{
  template<typename T1, typename T0, unsigned int... TDIM0, class> friend inline const MyClass<T0, TDIM0...> myFunction(const T1& x, const MyClass<T0, TDIM0...>& y);
};

template<typename T0, typename T, unsigned int... TDIM, class = typename std::enable_if<std::is_fundamental<T0>::value>::type> inline const MyClass<T, TDIM...> myFunction(const T0& x, const MyClass<T, TDIM...>& y)
{
  std::cout<<"It works !"<<std::endl;
  return MyClass<T, TDIM...>(y);
}

// friendfunction.cpp
#include "friendfunction.h"
int main(int argc, char *argv[])
{
  MyClass<double, 3, 3> myClass;
  myFunction(10, myClass);
  return 0;
}

With g++ (4.6.1) I compile with :

g++ -Wall -Wextra -Winline -Wno-unused -O3 -std=c++0x friendfunction.cpp -o friendfunction

And with intel ICPC (12.1.0 20111011) :

icpc -Wall -Wno-unused -O3 -std=c++0x friendfunction.cpp -o friendfunction

With g++ I got no error and no warning, but with Intel C++ I have the following warning :

friendfunction.h(5): warning #2922: template parameter "<unnamed>" cannot be used because it follows a parameter pack and cannot be deduced from the parameters of function template "myFunction"
template<typename T1, typename T0, unsigned int... TDIM0, class> friend inline const MyClass<T0, TDIM0...> myFunction(const T1& x, const MyClass<T0, TDIM0...>& y);

Does someone have a solution to avoid that ?

Furthermore, do you find the syntax of the friend function perfectly ok/secure or do you think that it can produce errors for some weird cases ?


Solution

  • just guessing, but it appears that icpc wants the parameter pack to be the last template argument. If the variadic parameter in the pack cannot be distinguished from another parameter following the pack, then this is justified, IMHO. But in your case, the variadic parameters are integers and the next one is a class type, so it appears that icpc got that wrong ...