Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Questions about forcing a single instance of a templated class.

27 views
Skip to first unread message

Robert Heller

unread,
May 12, 2021, 10:03:11 AM5/12/21
to
I am writing a class that works with the PRUs on a TI AM335X processor running
Debian Linux (Buster) -- this is a Beagle board. This class interfaces with
the PRUs using the Remote Process messaging protocol. There are exactly 2
PRUs and in this application, both PRUs are running the same program (with
minor differences), specificly the PRUs are generating a NMRA DCC waveform,
one for the main operations track and one for the programming track.

My template looks like this:

template <uint8_t PRU_NUM>
class CommandStationDCCPRUTrack :
public StateFlow<Buffer<dcc::Packet>
, QList<1>>
{
public:
static_assert(PRU_NUM < 2, "Only 2 PRUs, 0 and 1!");
static constexpr const uint8_t PRU = PRU_NUM;
CommandStationDCCPRUTrack(Service *service, int pool_size,
const char *firmwareName)
: StateFlow<Buffer<dcc::Packet>, QList<1>>(service)
, pool_(sizeof(Buffer<dcc::Packet>), pool_size)
{
hasInstance_ = true;
...
}
~CommandStationDCCPRUTrack()
{
hasInstance_ = false;
...
}
private:
static bool hasInstance_;
}

and I have this in a C++ file:

template <uint8_t PRU_NUM> bool CommandStationDCCPRUTrack<PRU_NUM>::hasInstance_ = false;

(elsewhere in the code I have this:

// The DCC output interface for the OPS track
static std::unique_ptr<CommandStationDCCPRUTrack<0>> mainDCC;
// The DCC output interface for the Pog track
static std::unique_ptr<CommandStationDCCPRUTrack<1>> progDCC;
)

When I compile this it compiles fine, but I get link errors, complaining that
there are undefined references to

CommandStationDCCPRUTrack<(unsigned char)0>::hasInstance_ and
CommandStationDCCPRUTrack<(unsigned char)1>::hasInstance_

The compiler does not like it when I include something like

template <uint8_t PRU_NUM> bool CommandStationDCCPRUTrack<0>::hasInstance_ = false;
template <uint8_t PRU_NUM> bool CommandStationDCCPRUTrack<1>::hasInstance_ = false;

I am using the stock G++ compiler on the BeagleBone:

lucy% g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/8/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Debian 8.3.0-6'
--with-bugurl=file:///usr/share/doc/gcc-8/README.Bugs
--enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++ --prefix=/usr
--with-gcc-major-version-only --program-suffix=-8
--program-prefix=arm-linux-gnueabihf- --enable-shared --enable-linker-build-id
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu
--enable-libstdcxx-debug --enable-libstdcxx-time=yes
--with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libitm
--disable-libquadmath --disable-libquadmath-support --enable-plugin
--enable-default-pie --with-system-zlib --with-target-system-zlib
--enable-objc-gc=auto --enable-multiarch --disable-sjlj-exceptions
--with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb
--disable-werror --enable-checking=release --build=arm-linux-gnueabihf
--host=arm-linux-gnueabihf --target=arm-linux-gnueabihf
Thread model: posix
gcc version 8.3.0 (Debian 8.3.0-6)

With these compile flags:

-std=c++0x -g3 -O0 -march=armv7-a

What am I doing wrong?

--
Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services
hel...@deepsoft.com -- Webhosting Services

0 new messages