This question already has answers here:
How to call through a member function pointer?
(2 answers)
Closed 4 years ago.
I try to give a reference to a member function (func) to a function (Multiprotocol) and call it with an object (z) of this class.
But i have problems with the line
result = z.*f(std::forward<Args>(args)...));
I tried things like
z.(*f) (std::forward<Args>(args)...))
and
z.(*(&f)(std::forward<Args>(args)...));
But i don't knwow how to this. Can anybody help me?
class test
{
public:
static int func()
{
std::cout << "in func";
}
};
class MultiProtocol
{
public:
template<typename Function, typename... Args>
bool functionImpl(Function f, Args&&... args)
{
int result = 0;
result = z.*f(std::forward<Args>(args)...));
return result;
}
private:
test z;
};
Main is:
int main()
{
MultiProtocol rr;
rr.functionImpl(&test::func);
}
Nearly, it is:
(z.*f)(std::forward<Args>(args)...)
Cannot be
z.(*f) (std::forward<Args>(args)...))
z.(*(&f)(std::forward<Args>(args)...));
as we should use operator .* (or ->*).
z.*f(std::forward<Args>(args)...) would be valid if f(args...) would return int test::* (pointer on member) as it is actually z .* (f(std::forward<Args>(args)...)).
Related
This question already has answers here:
Why do I have to access template base class members through the this pointer?
(3 answers)
ISO C++ Standard - rules regarding examining dependent base. Why?
(1 answer)
Closed 8 months ago.
This code doesn't compile:
#include<iostream>
using namespace std;
template<class T>struct Base {
void f(int) { cout << "Base::f() int\n"; }
};
template<class T>struct Derived:Base<T> {
void g(int i) { f(i); } // should be this->f(i) to pass compile
};
int main(){
Derived<char> obj;
obj.g(1); // cfunction short
return 0;
}
I googled and search on stackoverflow, it says that in the error-line, I should use write either
void g(int i) { this->f(i); }
or
void g(int i) { Base<T>::f(i); }
Yes, they work. I tried none-template version, doesn't need this complex qualifier. As long as both f() and g() doesn't use any template type parameter, I didn't think of a rule on template deduction upon these 2 functions.
Is this some hidden rule behind template resolution that I should add extra qualifier, and why my original code fail to compile?
This question already has answers here:
C++ Overload Static Function with Non-Static Function
(5 answers)
Closed 7 years ago.
I was looking into a function overloading problem listed below and found that the following code doesn't compile.
#include<iostream>
class Test {
static void fun(int i) {}
void fun(int i) {}
};
int main()
{
Test t;
return 0;
}
My understanding was that member functions when compiled implicitly have an extra parameter, a pointer to the object in the compiled function. I am not sure what happens to the static functions. Now to figure out what the compiler was doing I tried running g++ -fdump-tree-all failed_overload.cxx and I got the files listed below:
failed_overload.cxx.001t.tu
failed_overload.cxx.002t.class
failed_overload.cxx.003t.original
failed_overload.cxx.004t.gimple
failed_overload.cxx.204t.statistics
I looked into gimple output and found the following:
**
static void Test::fun(int) (int i)
{
GIMPLE_NOP
}
void Test::fun(int) (struct Test * const this, int i)
{
GIMPLE_NOP
}
**
It seems like the static function just has the int parameter but the member function has the extra this parameter. If that is the case why is the compilation failing and why cant we overload the static function with the same signature.
If you had both static and non-static functions taking the same set of parameters, then in a call from a method of the class (non-static) it would be impossible to distinguish whether the programmer wants to call static or non-static function. Example:
#include<iostream>
class Test {
static void fun(int i) { std::cout << 2*i; }
void fun(int i) { std::cout << i; }
void otherFunc() {
fun(3); // Ambiguity: is static or non-static function intended?
}
};
int main()
{
Test t;
t.otherFunc();
return 0;
}
This question already has answers here:
How do you pass a member function pointer?
(6 answers)
Closed 9 years ago.
I have a class
class A{
A(/*constructor arguments*/);
double MethA(double);
};
And I want to pass the method MethA in a function that takes a pointer to a function :
double function(double (*f)(double), double x){
return f(x);
}
So what I'm doing is to call
A a(/*constructor arguments*/);
function(a.MethA,1.0);
but it doesn't compile.
I'm pretty sure that this question is answered somewhere else, but I couldn't find where because I'm not sure that the terminology I use is correct. Am I trying to pass a pointer on a class method as a function argument ? Or, to pass a function pointer as a member of a class... I'm confused :-(
When you need to use a pointer to member function, you need to pass two separate things:
what member function to call and
what instance to call it on.
In C++, you can't combine them in one construct, like you want to:
A a;
bar(a.foo);
is not valid C++.
Instead, you have to do this:
A a;
bar(a, &A::foo)
And declare and implement bar() accordingly:
void bar(A &a, void (A::*method)()) {
a.*method();
}
See Arkadiy's answer if you want to see how to properly use member function pointers.
BUT
As requested in the comments: if the compiler you are using supports lambdas (some without full C++11 do). You can do something like the following, which looks more like the syntax you are attempting to use.
Your definition for function changes to something like:
template <typename F>
double function(F f, double x){
return f(x);
};
a function template that accepts a parameter that is callable with a double.
At your call-site you do this:
A a(/*constructor arguments*/);
function([&](double x){return a.MethA(x);},1.0);
That generates a function object in-place that is bound to your class instance a by reference.
The template can be made fully typesafe with some magic in <type_traits>, but as-is it will give you template spew if you pass something very wrong.
It has to be a static function!
#include <iostream>
#include <cassert>
class A {
public:
static double MethA(double x) { return 5 * x; }
};
typedef double (*ftype)(double);
double function(ftype f) {
assert(f != NULL);
return f(7);
}
int main(int, char**) {
// expect "35\n" on stdout
std::cout << function(A::MethA) << "\n";
}
It has to be static because you can't access any of A's variables without knowing which A object are you refering to! If you need A's non-static member variables, you need to pass a reference to an a into the static function:
#include <iostream>
#include <cassert>
class A {
double fX;
public:
A(double x) : fX(x) { }
double methB(double x) const { return fX * x; }
static double MethB(double x, const A& a) {
return a.methB(x);
}
};
typedef double (*ftype2)(double, const A&);
double function_with_context(ftype2 f, const A& a) {
assert(f != NULL);
return f(7, a);
}
int main(int, char**) {
A a(6);
// expect "42\n" on stdout
std::cout << function_with_context(A::MethB, a) << "\n";
}
But it's sometimes better to use inheritance and polymorphism to achieve this sort of interface:
#include <iostream>
class MyInterface {
public:
virtual double f(double x) const = 0;
};
class A : public MyInterface {
double fX;
public:
A(double x) : fX(x) { }
double f(double x) const {
return fX * x;
}
};
double function(const MyInterface& o) {
return o.f(7);
}
int main(int, char**) {
A a(6);
// expect "42\n" on stdout
std::cout << function(a) << "\n";
}
This question already has answers here:
static const Member Value vs. Member enum : Which Method is Better & Why?
(6 answers)
Closed 10 years ago.
I stumbled upon this answer to a question about powers of integers in c++: https://stackoverflow.com/a/1506856/5363
I like it a lot, but I don't quite understand why the author uses one element enums as opposed to some integer type explicitly. Could someone explain?
AFAIK this has to do with older compilers not allowing you to define compile-time constant member data. With C++11 you could do
template<int X, int P>
struct Pow
{
static constexpr int result = X*Pow<X,P-1>::result;
};
template<int X>
struct Pow<X,0>
{
static constexpr int result = 1;
};
template<int X>
struct Pow<X,1>
{
static constexpr int result = X;
};
int main()
{
std::cout << "pow(3,7) is " << Pow<3,7>::result << std::endl;
return 0;
}
This question already has answers here:
Overload resolution with std::function
(2 answers)
Closed 6 years ago.
consider some code:
void foo() { }
bool bar() { return true; }
struct S
{
void operator=(std::function<void()> f){f();};
void operator=(std::function<bool()> f){f();};
};
int main() {
S s;
s = foo; // ok
s = bar; // error: use of overloaded operator '=' is ambiguous
}
How can I make this example unambiguous?
The problem you're running into is that std::function<void(Args...)> is allowed to discard return types - so both std::function<void()> and std::function<bool()> can be constructed from a bool(*)(). The latter will forward through the return from bar, but the former will just discard it. That's perfectly valid behavior, but causes this to be ambiguous.
What you probably want is to avoid std::function altogether:
template <class F>
void operator=(F f) { f(); }