0

This is similar to How to allow template function to have friend(-like) access?, but I'm working with a static template function (non-member). I'm trying to accomplish the following.

Integer.h:

class Integer {    
    ...
    // Forward declare due to static
    template <typename T> static Integer StringToInteger(const T *str, ByteOrder order);
    // Provide friendship
    template <typename T> friend Integer StringToInteger(const T *str, ByteOrder order);
};

Integer.cpp:

// T will be a char or wchar_t
template <class T>
static Integer StringToInteger(const T *str, ByteOrder order)
{
    ...
}

When declaring the friendship, the static template function is causing the error:

$ make
c++ -DDEBUG -g3 -O1 -fPIC -Wno-tautological-compare -DCRYPTOPP_DISABLE_ASM -pipe -c integer.cpp

integer.cpp:2970:16: error: static declaration of 'StringToInteger' follows
      non-static declaration
static Integer StringToInteger(const T *str, ByteOrder order)
               ^
./integer.h:380:42: note: previous declaration is here
    template <typename T> friend Integer StringToInteger(const T *str, B...

But according to Is it possible to declare a friend function as static?, I need to forward declare the function as static.

Question: How do I provide friendship to a static template function?


If I add static to the friend declaration, then I get another error:

// Forward declaration to retain static
// template <typename T> static Integer StringToInteger(const T *str, ByteOrder order);
template <typename T> friend static Integer StringToInteger(const T *str, ByteOrder order);

Then it results in:

$ make
c++ -DDEBUG -g3 -O1 -fPIC -Wno-tautological-compare -DCRYPTOPP_DISABLE_ASM -pipe -c integer.cpp

In file included from integer.cpp:8:
./integer.h:380:34: error: 'static' is invalid in friend declarations
    template <typename T> friend static Integer StringToInteger(const T ...

If I try to declare friendship on a specialization:

// Forward declaration to retain static
template <typename T> static Integer StringToInteger(const T *str, ByteOrder order);
friend Integer StringToInteger<char>(const char *str, ByteOrder order);

Then I get another error:

$ make
c++ -DDEBUG -g3 -O1 -fPIC -Wno-tautological-compare -DCRYPTOPP_DISABLE_ASM -pipe -c integer.cpp

In file included from integer.cpp:8:
./integer.h:381:20: error: no function template matches function template
      specialization 'StringToInteger'
    friend Integer StringToInteger<char>(const char *str, ByteOrder order);

$ c++ --version
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin12.6.0
Thread model: posix
Community
  • 1
  • 1
jww
  • 97,681
  • 90
  • 411
  • 885
  • I stripped out a bit of stuff and put this in ideone using GCC: http://ideone.com/NOHKz7 which is essentially what you have. It seems to work. So I am unsure why you're getting errors. – qeadz Mar 30 '15 at 19:47
  • I'm a bit confused what you want to express with static template free function? – Lol4t0 Mar 30 '15 at 19:47
  • @qeadz - oh, man... that probably means its a bug in Apple's Clang. Do you know of any workarounds? If the change can't support modern compilers, then I can't make the change. – jww Mar 30 '15 at 19:50
  • @Lol4t0 - I'm sorry, but I don't know what a *"static template free function"* is. Please forgive my ignorance. What is a *"static template free function"*? – jww Mar 30 '15 at 19:53
  • @jww, well, I misslooked that is is class member function. Still I don't understand what is the reason of simultanious _static_ and _friend_. And you also used static in the 2 menanings: of static class member function and static linkage. – Lol4t0 Mar 30 '15 at 20:01

1 Answers1

1

Given the StringToInteger declared in the .cpp is a free function, try this in the header:

class Integer;

// Forward declare due to static
template <typename T> static Integer StringToInteger(const T *str);

class Integer {    
  public:
  // Provide friendship
  template <typename T> friend Integer StringToInteger(const T *str);
};
qeadz
  • 1,476
  • 1
  • 9
  • 17
  • Ah, that was it. I had to forward declare it outside of the class declaration. Thanks. – jww Mar 30 '15 at 20:08