gct
gct

Reputation: 14563

How to define static member variable from class template with specialization?

OK I have this code:

// default implementation just uses a mutex to serialize access
template <typename T, typename=void>
struct kernport {
    static const bool atomic = false;

    // constructor
    kernport(T value=T()) {
        set(value);
    }

    // get/set value
    T    get()         const { std::unique_lock<std::mutex> lock(lock_); return value_;  }
    void set(const T& value) { std::unique_lock<std::mutex> lock(lock_); value_ = value; }

private:
    mutable std::mutex lock_;
    T value_;
};


// specialization if std::atomic<T> exists
template <typename T>
struct kernport<T, void_type<decltype(std::atomic<T>())>> {
    static const bool atomic = true;

    // constructor
    kernport(T value=T()) {
        set(value);
    }

    // query port value
       T get() const         { return value_.load(std::memory_order_acquire);  }
    void set(const T& value) { value_.store(value, std::memory_order_release); }

private:
    std::atomic<T> value_;
};

If I try to check kernport<bool>::atomic, I get the dreaded undefined reference. OK, so I need to define the member outside of the class:

template <typename T> const bool kernport<T>::atomic;

Unfortunately, doing that, I get:

inc/skunk/dataflow/kernel.h:472:47: error: template definition of non-template ‘const bool sk::kernport::atomic’ template const bool kernport::atomic;

And for the life of me I can find the right syntax. How do I write this?

Upvotes: 0

Views: 82

Answers (1)

max66
max66

Reputation: 66200

Maybe

template <typename T1, typename T2>
const bool kernport<T1, T2>::atomic;

template <typename T1>
const bool kernport<T1, void>::atomic;

?

Don't forget the second (defaulted to void) template parameter.

Upvotes: 1

Related Questions