mercredi 18 avril 2018

Possible to force something to be extern but also a constant expression a non-type template param?

Using C++11, g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18).

Lets pretend I have a templated function (pardon my terminology if it isn't quite right).

I want to perform a "general" algorithm based on what was supposed to be compile-time instances of "field". Where the only things that really changed are these constants which I moved into trait classes (only added one here but imagine there are more). Originally I was declaring it as

constexpr field FIELD1{1};

However in C++11, non-type template params need to have external linkage (unlike C++14 which can have internal and external linkage?). So because not's in the same translation unit I needed to use extern in order to give it external linkage (sorry if I butchered that explanation also). But by defining it extern I can't define it using constexpr and it seems that be losing that constexpr constructor this field is no longer a valid constant expression to qualify as a non-type template param.

Any suggestions if there is some way I can get around this? Open to a new method of doing things. Below is a simplified (incomplete, and non-compiling version to get the gist of the organization).

So the error I am seeing is along the lines of

error: the value of ‘FIELD1’ is not usable in a constant expression

note: ‘FIELD1’ was not declared ‘constexpr’ extern const field FIELD1; Not quite sure what could be a best alternative.

I can get rid of the second error by removing the constexpr from the constructor. But then I don't know how to approach the constant expression issue.

field.H

struct field
{
    int thingone;

    constexpr field(int i):thingone(i){}
};

extern const field FIELD1;

field.C

#include "field.H"
const field FIELD1{0};

field_traits.H

#include "field.H"

template< field T >
class fieldTraits;

template< >
class fieldTraits<FIELD1>
{
    public:
        // Let's say I have common field names
        // with different constants that I want to plug
        // into the "function_name" algorithm
        static constexpr size_t field_val = 1; 
};

function.H

#include "field.H"

template< field T, typename TT = fieldTraits >
void function_name()
{
    // Let's pretend I'm doing something useful with that data
    std::cout << T.thingone << std::endl;
    std::cout << TT::field_val << std::endl;
}

Aucun commentaire:

Enregistrer un commentaire