samedi 28 novembre 2015

Forcing template member function to instantiate

I have a class C in the namespace N with a public template member function F as follows:

namespace N {
    class C {
    public:
        template<int I>
        void F() {
            // ...
        }
    };
};

The values of I for N::C::F<I> are not known until runtime. However, the value of I is constrained such that 0 <= I < 2^8. I am looking for a way to force this function to expand the template to all 256 possible forms.

So far, I have manually created a static array within a second function of C that points to every possible function:

        template<int I>
        void F() {
            // ...
        }

        void G(int I) {
            static void(* const funcs[256])() = {
                F<0>, F<1>, F<2>, ...
            };

            funcs[I]();
        }

though I am left wondering if there is a better way. I already have a macro in N that is responsible for constructing a separate struct for each value of I (for use by F itself) and was looking if I could possibly integrate the instantiation of the template member function somehow in it:

    template<int> struct S;

    #define M(I, n) \
        template<> struct S<I> { \
            static const char name[] = #n; \
            /*
                Some how instantiate the function here, like (just guessing here):

                static const SEvaluator<I> eval = &C::F<I>;

                given

                template<int I>
                using SEvaluator = void(*)();
            */
        };

    M(0, "foo"); M(1, "bar");

    #undef M

My proposed method does not work as is and the compiler complains about F not being a constexpr. F manipulates several variables of C and calls external methods and could not be declared constexpr. Is there a way to salvage this or do I have to resort to my first hackish method?

Aucun commentaire:

Enregistrer un commentaire