2

I'm writing a templated singleton superclass, that can provide a thread-local instance or a process-global instance. The code below compiles and technically fits my need. But, how can I write the function implementation outside of the class declaration? How do I declare the function in the class (is the commented line right)?

All similar questions implement the function in the class declaration.

#include <vector>
#include <type_traits>


using namespace std;

template <class t, bool tls=true>
class A{
public:
  typedef std::vector<t> Avector;
//  static Avector& getVector();

  template <class T=t, bool TLS=tls, typename std::enable_if<!TLS>::type* = nullptr>
  static Avector&
  getVector(){
    static Avector v=Avector();
    return v;
  }

  template <class T=t, bool TLS=tls, typename std::enable_if<TLS>::type* = nullptr>
  static Avector&
  getVector(){
    static thread_local Avector v=Avector();
    return v;
  }
};

int main(){
  vector<int>& vi = A<int>::getVector();
  vector<double>& vd = A<double, false>::getVector();
  return 0;
}
Joachim
  • 41
  • 5
  • Instead of SFINAE on the TLS bool, just use the bool directly and specialize for true and false. – rubenvb Jun 09 '17 at 14:27
  • @rubenvb You can't partially specialize a function, although from the code above, I don't see why the function are templates – Passer By Jun 09 '17 at 14:48
  • Right, then you use helper structs like you did in your answer ;) – rubenvb Jun 09 '17 at 15:10
  • The advantage of using SFINAE in this case is, that I can use the same class A for thread-local and per-process instances. The posted code is just a minimal reproducer. The actual class A in my application provides more methods. – Joachim Jun 10 '17 at 11:29

1 Answers1

1

You can instead write

template<typename T, bool>
struct A
{
    typedef std::vector<T> Avector;
    static Avector& getVector();
};

template<typename T, bool b>
typename A<T, b>::Avector& A<T, b>::getVector()
{
    thread_local typename A<T, true>::Avector v;
    return v;
}

template<typename T>
class A<T, false>
{
    typedef std::vector<T> Avector;
    static Avector& getVector();
};

template<typename T>
typename A<T, false>::Avector&  A<T, false>::getVector()
{
    static typename A<T, false>::Avector v;
    return v;
}

Also, generally singletons shouldn't be used

Passer By
  • 18,098
  • 6
  • 45
  • 90
  • My question was, how to implement the function outside of the class declaration. This answer again implements the function in the declaration. Further, my real code has more functions and with above approach, I can aviod code duplication. – Joachim Jun 09 '17 at 18:16
  • @Joachim Do you mean what the syntax is for defining the method outside the class? – Passer By Jun 10 '17 at 06:19
  • Yes, I couldn't find the syntax to define the methods in my code outside of the class declaration. – Joachim Jun 10 '17 at 11:24