Home > Blockchain >  Explicit instantiation of template class with templated member functions
Explicit instantiation of template class with templated member functions

Time:10-22

With a class defined as follows:


template <typename T>
class A {
    private:
    T a;

    public:
    A(T& a) : a_(a) { }

    template <typename D>
    void Eval(D& arg)
    {
        // ...
    }
};

template A<int>;

I want to explicitly instantiate one instance of the class, and I want this class to have one explicit instantiation of Eval. The intention here is to get a member function pointer that avoids ambiguity:

auto eval_ptr = &A<int>::Eval;

CodePudding user response:

The ambiguity is not coming from anything to do with template instantiation, it's caused by Eval being a templated function.

&A<int>::Eval does not point to a function, it points to a template. And there is just no such type as a "pointer to a template".

If you want a pointer to A<int>::Eval, you need to specify D as well.

auto eval_ptr = &A<int>::Eval<int>; works just fine for example.

Addendum: Pointers-to-templates do exist in the grammatical sense, but there is no type an object can have to hold one of them. They must be immediately casted/decayed to a specific overload in order to be used, which doesn't come into play here since you want to store it in an auto.

For example: The following is fine because there's clearly only one "version" of Eval that can be meant:

void bar(void (A<int>::*arg)(int&)) {}

void foo() {
    bar(&A<int>::Eval);
}

CodePudding user response:

The very simple solution was specifying both template parameters:

template <typename T>
class A
{
private:
    T a;

public:
    A(T &a) : a_(a) {}

    template <typename D>
    void Eval(D &arg)
    {
        arg =1;
    }
};
int main()
{
    auto p = &A<int>::Eval<int>;
}
  • Related