2

I am trying to make a type alias for a function (myFunction) inside myClass.

template<typename T>
using calc_t = matrix<T> (MyClass<T>::*myFunction)(const matrix<T> &X);

Where I would get a generic syntax error, missing ')' before MyClass<T>::*myFunction.

And then using it as so

calc_t<double> fptr = &MyClass<double>::myFunction;

I am not sure on the syntax to use in this specific case for when using the using type alias as opposed to a non-templated typedef.

I have looked at the following other SO questions that don't seem to cover this specific usage:

I have tried some other variants but to no success.

Roy
  • 3,027
  • 4
  • 29
  • 43
  • 2
    Do you get an error? What is the error? A [MCVE] with the class definition would be useful. – clcto Jun 25 '18 at 22:26
  • I really recommend against using pointers to member functions (or pointers to *any* function). Instead I suggest using the more generic [`std::function`](http://en.cppreference.com/w/cpp/utility/functional/function). – Some programmer dude Jun 25 '18 at 22:26
  • @clcto I have added the type of error I get in this case. You are right. I might port it over the std::function, once I understand this a bit more. – Roy Jun 25 '18 at 22:31

2 Answers2

3

It looks like the issue is that you are trying to name the function pointer on the right side as well. The following compiled for me:

template <typename T>
class Matrix { };

template <typename T>
class MyClass
{
public:
    Matrix<T> myFunc() { return {}; }
};

template <typename T>
using my_f = Matrix<T> (MyClass<T>::*)(); // NOTE: No myFunction here

int main() {
    my_f<double> f = &MyClass<double>::myFunc;
    return 0;
}

https://www.ideone.com/VdazMB

clcto
  • 9,530
  • 20
  • 42
  • Ah, I think that is it. I'm just going to check through my code to see it all works, then I'll accept the answer. Thank you very much. I did try a similar approach but didn't use :: which is why it didn't work for me. – Roy Jun 25 '18 at 22:39
2

As an alternative, and as I already suggested in a comment, you could use std::function as it will be easier to use and more generic.

template <typename T>
class matrix { };

template <typename T>
class MyClass
{
public:
    matrix<T> myFunction(matrix<T> const&) { return {}; }
};

template<typename T>
using calc_t = std::function<matrix<T>(matrix<T> const&)>;

int main()
{
    MyClass<double> myObject;

    using namespace std::placeholders;  // For e.g. _1
    calc_t<double> myFunction = std::bind(&MyClass<double>::myFunction, myObject, _1);

    matrix<double> myFirstMatrix, mySecondMatrix;
    myFirstMatrix = myFunction(mySecondMatrix);
}

As shown above, you could use std::bind. But you could also use lambda expressions:

calc_t<double> myFunction = [&](matrix<double> const& m)
{
    return myObject.myFunction(m);
};

Or better yet (for this simple use-case anyway) use type-deduction

auto myFunction = [&](matrix<double> const& m)
{
    return myObject.myFunction(m);
};

With lambdas, type-deduction and templates you can create very generic and expressive and complex code in a simple way.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • That is a really great and thorough answer. I have just been dabbling with `std::function` and it definitely seems to be something I should be using. Thanks for explaining how to improve my code! – Roy Jun 25 '18 at 23:02