2

I am trying to get the address of a static method from a class that is passed as a template argument to another class. Below is a pared down example:

#include <iostream>
#include <array>

using namespace std;

typedef size_t Data;

class MyFunction
{
private:
    static const std::array<std::string, 3> values;

public:
    template<size_t N>
    static void Func(const Data& aData)
    {
        size_t index = (N > aData ? 2 : (N == aData ? 1 : 0) );
        cout << "Function::Func<"<< N << ">:\t" << N << values[index] << aData << endl;
    }

    typedef decltype(&Func<0>) type;    
};

const std::array<std::string, 3> MyFunction::values {"<", "=", ">"};

template<class Function, size_t N>
class FunctionManager
{
private:
    static const typename Function::type func_;

    static constexpr typename Function::type Create()
    {
        return &Function::Func<N>; //ERROR: Causes "overloaded function with no contextual information".
    }
public: 
    void operator()(const Data &aData) const
    {
        func_(aData);
    }
};

template<class Function, size_t N>
const typename Function::type FunctionManager<Function, N>::func_ = FunctionManager<Function, N>::Create();

int main()
{
    static const size_t N = 6;
    auto man = FunctionManager<MyFunction, N>();
    man(N/2);
    return 0;
}

You can also find the code here. The problem is in the Create() function, I get "address of overloaded function with no contextual type information" error. However, if I change &Function::Func to &MyFunction::Func, it works fine. I would like to make the actual function a template parameter and not hard-code it, anyone have any idea how to fix this problem? Note that I realize there are simpler ways of doing what I'm trying to do, but the actual code instead of a single Function::type creates an array of them using the index trick, etc. Any help would be greatly appreciated.

  • `&Function::template Func` - the compiler doesn't know that you have a template there and expects a value by default. – Xeo Oct 25 '13 at 18:35
  • possible duplicate of [Where and why do I have to put the "template" and "typename" keywords?](http://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords) – Xeo Oct 25 '13 at 18:35
  • Smells a bit like XY problem, could you elaborate more about purpose of your `Create()` function, and why you don't want to 'hardcode' the concrete function's reference? How do you intend clients using this interface? Arbitrarily selecting from their static methods to pass one? – πάντα ῥεῖ Oct 25 '13 at 18:36

1 Answers1

4

The error message causes some head scratching, indeed. Here's what's missing:

return &Function::template Func<N>;
//                ^^^^^^^^

Function is a template parameter and you need to help the compiler and tell it that the nested name Func names a template.

jrok
  • 54,456
  • 9
  • 109
  • 141