1

I'm not used to C++ templates, and I have a problem using the libraries made with templates.

These are math-related libraries included in Numerical Methods in C 3rd edition, and I got a problem with using the methods.

Below is the function that I'm trying to use:

// roots.h
//...
template <class T>
// Doub is a defined type that is equal to double
Doub rtbis(T &func, const Doub x1, const Doub x2, const Doub xacc) {
    const Int JMAX=50;
    Doub dx,xmid,rtb;
    Doub f=func(x1);
    Doub fmid=func(x2);
    if (f*fmid >= 0.0) throw("Root must be bracketed for bisection in rtbis");
    rtb = f < 0.0 ? (dx=x2-x1,x1) : (dx=x1-x2,x2);
    for (Int j=0;j<JMAX;j++) {
        fmid=func(xmid=rtb+(dx *= 0.5));
        if (fmid <= 0.0) rtb=xmid;
        if (abs(dx) < xacc || fmid == 0.0) return rtb;
    }
    throw("Too many bisections in rtbis");
}
//...

And with this, in main.cpp I tried to call

// main.cpp
#include "nr3.h"
#include "roots.h"
#include "bessel.h"

int main() {
    Doub (Bessjy::*fptr) (Doub) = &Bessjy::j0;
    Doub root = 0;

    root = rtbis<double (Bessjy::*)(double)>(fptr,1.0,10.0,0.000001);

    std::cout << root << std::endl;
}

I used g++ to compile, and the error message saids:

error: called object type 'double (Bessjy::*)(double)' is not a function or function pointer
Doub f=func(x1);
note: in instantiation of function template specialization
'rtbis&lt;double (Bessjy::*)(double)&gt;' requested here
root = rtbis&lt;double (Bessjy::*)(double)'&gt;(fptr,1.0,10.0,0.000001);

I modified the code as the compiler told me to do, but still it repeats the same error message.

I don't get how to solve it. Certainly I'm missing the important syntax matter.

8
  • 1
    The error message you posted does not seem complete. Part of it is missing. Can you please post the complete error message? What modification did you make based on the error message from the compiler? Commented Sep 28, 2018 at 5:25
  • 2
    Is Bessjy::j0 a static function? Commented Sep 28, 2018 at 5:35
  • 1
    Thanks for the complete error message. Looks like you are trying to call member function Bessjy::j0() with x1 as the first argument on the line corresponding to the error message. However, since this is a member function (probably not a static based on the error message), you can only call it on an object of type Bessjy. See this for some details. For an example of how you would do this in your code, see this. Commented Sep 28, 2018 at 5:37
  • 1
    And, as @Swordfish asked, if Bessjy::j0() were a static member function then you can make your code work with some modifications. Here is a simplified example. Commented Sep 28, 2018 at 5:54
  • 1
    Great. I summarized the solution as an answer below. Hope that is what worked for you. :D Commented Sep 28, 2018 at 6:11

1 Answer 1

2

(Posting this for completion, based on discussion in comments, for others to find if they have similar questions).

Since Bessjy::j0() is a static member function, as mentioned in comments below the question, its type is the same as if it were an ordinary function. You can pass it as an argument to rtbis<>() just like any other ordinary function. Here is an example:

#include <iostream>

using Int = int ;
using Doub = double ;

class Bessjy
{
public:
    static Doub j0(Doub x1) { return x1*x1 + 60.0 ; }     
} ;

template <class T>
Doub rtbis(const T& func, const Doub x1, const Doub x2, const Doub xacc) { 
    return func(x1) ;
}

int main() 
{
    const auto root = rtbis(Bessjy::j0,1.0,10.0,0.000001);
    std::cout << root << std::endl;
    return 0 ;
}

Try it online here. Read this for additional information and caveats.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.