0

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?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
gct
  • 14,100
  • 15
  • 68
  • 107

1 Answers1

1

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.

max66
  • 65,235
  • 10
  • 71
  • 111
  • Doesn't seem to work either way, I get the undefined reference again when it does compile. – gct Sep 30 '19 at 22:54
  • @gct - Sorry: error of mine: I've seen `atomic` in the specialization but not in the main version. I'm too tired today. – max66 Sep 30 '19 at 22:57
  • Two template parameters doesn't work either, I get an undefined reference error. – gct Sep 30 '19 at 23:00
  • @gct - with both? One for the main, one for the specialization? – max66 Sep 30 '19 at 23:05
  • I get "template definition of non-template " with the second statement. – gct Sep 30 '19 at 23:11
  • @gct - the bad part is that I compile it (and link) in a toy example... frankly I don't know where is the problem. – max66 Sep 30 '19 at 23:13
  • I'm finding my specialization doesn't work either, because std::atomic uses a static_assert which breaks SFINAE... – gct Sep 30 '19 at 23:13