So in my C++11 project, I'm trying to alias a specific traits template specialisation based on a class template parameter. This is intended so that I can inherit from the template, using CRTP, and access the members of the traits template without needing to refer to the type used to specialise it.
improved minimal example:
main.cpp
#include "Matrix.h"
#include "MatrixImplementation.h"
int main()
{
HAL_Matrix<NXP_HAL_Matrix>().Scan();
return 0;
}
Matrix.h
#pragma once
#include <array>
template <uint8_t ... Pins>
static constexpr std::array<uint8_t, sizeof...(Pins)> MakePinArray()
{
return (std::array<uint8_t, sizeof...(Pins)> { { Pins... } });
};
template <class HAL_Matrix_Implementation>
struct MatrixTraits
{
};
template <>
struct MatrixTraits<class HAL_Matrix_Implementation>
{};
template <class HAL_Matrix_Implementation>
class HAL_Matrix
{
public:
using MatrixParameters = ::template MatrixTraits<HAL_Matrix_Implementation>;
void Scan()
{
auto test = MatrixParameters::RowPins;
auto test2 = MatrixParameters::ColumnPins;
};
};
MatrixImplementation.h
#pragma once
#include "Matrix.h"
#include <array>
#include <stdint-gcc.h>
class NXP_HAL_Matrix : public HAL_Matrix<NXP_HAL_Matrix>
{
public:
void Scan() {};
void Initialize() {};
};
template <>
struct MatrixTraits<NXP_HAL_Matrix>
{
public:
static constexpr auto RowPins = MakePinArray<1,2,3>();
static constexpr auto ColumnPins = 3;
};
At compile-time I get the following error:
Debug/main.o: In function `HAL_Matrix<NXP_HAL_Matrix>::Scan()':
<path>\Matrix.h(31): error VGDB1000: undefined reference to `MatrixTraits<NXP_HAL_Matrix>::RowPins'
While preparing this minimal example it became apparent to me that my attempt to access RowPins gives an undefined reference, but storing just an int in ColumnPins means I can access it without error. As a result I'm presuming that there's something wrong with my MakePinArray template function so that the compiler is ignoring the constexpr specifier, and allowing it to be called at runtime hence the undefined reference error.
However, I've looked at other answers such as the second suggestion in this answer: Create N-element constexpr array in C++11 and can't detect a functional difference between his build_array function and mine.
Can anybody a) confirm that my understanding is correct (ie that constexpr specifier is being discarded, causing there to be a declaration for RowPins but no definition) and b) suggest how I rectify this?
Just for further information if it is helpful, I'm using VisualGDB/arm-gcc 4.9.2 and compiling with -std=c++11
.