guhur
guhur

Reputation: 2856

Store templated argument into a namespace

I want to store a templated argument into my namespace.

I have no idea how to do that. This is a simplification of my code:

namespace sdc {
    template<typename T_output> 
    T_output last_o[dim_output];

    template<typename T_input, typename T_output>
    void training(T_input in[], T_output o_a[], T_output o_b[]) { 
        sdc::last_o = o_a;
    }
}

I get the error:

error: "last_o" is not a function or static data member

How could I do such a thing?

Upvotes: 0

Views: 62

Answers (2)

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145204

Instead of the given invalid code

namespace sdc {
template<typename T_output> 
T_output last_o[dim_output];
template<typename T_input, typename T_output>
void training(T_input in[], T_output o_a[], T_output o_b[]) { 
sdc::last_o = o_a;
}
}

… you can use a simple Meyers' singleton with std::vector, like this:

#include <vector>

namespace sdc {
    using std::vector;

    template< class Type > 
    auto last()
        -> vector<Type>&
    {
        static vector<Type> the_last;
        return the_last;
    }

    template< class Input, class Output>
    void training( vector<Input>& in, Vector<Output> a, Vector<Output> b )
    {
        sdc::last<Output>() = a;
    }
}  // namespace sdc

Do note well that this maintains a separate sdc::last() for each type Output.

If you want a common history for all types you will have to specify in more detail how you intend to access it.

Disclaimer: code not touched by compiler's hands.


As noted by @vsoftco in commentary on his answer, you can avoid the singleton by using a C++14 templated variable, exactly as in the original code except using e.g. a std::vector instead of a raw array, since raw arrays are not assignable. But doing so is ungood as a general convention, for two reasons. First, there is the notorious “static initialization order fiasco” pitfall to trap you when you least expect it. And secondly, not all readers of the code will know that the syntax is now supported – and presently that includes that not all compilers will know it.

Upvotes: 3

vsoftco
vsoftco

Reputation: 56547

The problem is the assignment

sdc::last_o = o_a;

You cannot assign to an array (std:: last_o is an array, and arrays are not pointers, they decay to pointers when passed by value as function arguments). Other than that the code should work, assuming dim_output is a constant expression.

And in any case, sdc::last_o is a variable template (introduced in C++14), so it should be std::last_o<TYPE> instead.

Upvotes: 1

Related Questions