Here is my usecase:
class A:
protected:
virtual void methodA1(const void* const s, const std::streamsize n) const;
inline void methodA2(const void* const s, const std::streamsize n) const;
class B : public A
private:
const char *a;
template <void (*T)(const void* const, const std::streamsize)>
void doOperation(const char* b) {
T(a, b - a);
}
//here comes the template usage
void methodB1(const char *x) {
doOperation<methodA1>(x);
}
void methodB2(const char *x) {
doOperation<methodA2>(x);
}
The problem is that will not compile. I get error like template argument deduction/substitution failed: and invalid use of non-static member function.
How could I achieve the desired behaviour ?
methodA1 is of type void (A::*)(const void* s, std::streamsize) const.
So you have to adjust your code to something like:
class A
{
public:
virtual void methodA1(const void* const s, const std::streamsize n) const = 0;
void methodA2(const void* const s, const std::streamsize n) const {}
};
class B : public A
{
private:
const char *a;
void methodA1(const void* s, std::streamsize n) const override {}
template <void (A::*M)(const void*, std::streamsize) const>
void doOperation(const char* b) {
(this->*M)(a, b - a); // method pointer usage
}
//here comes the template usage
void methodB1(const char *x) {
doOperation<&A::methodA1>(x);
}
void methodB2(const char *x) {
doOperation<&A::methodA2>(x);
}
};
I am trying to get multiple pointer in one get methods, without leaving the user the right to modify the data. Here is my implementation :
class A {
public:
bool getAB( int** a, int** b ) const
protected :
int * a_;
int * b_;
}
bool getAB( int** a, int** b ) const
{
*a = a_;
*b = b_;
return true;
}
But this way, user can modify, and even free the data.
I could implement like two different getter wich return const int*, but i would like to know if there is a correct way to do that.
In c++, the proper way to return multiple values is by reference:
class A {
public:
bool getAB( int*& a, int*& b ) const
{
a = _a;
b = _b;
}
protected :
int * a_;
int * b_;
}
(I also made the method inline to simplify the example)
If you want to disallow altering the data, return a pointer to const:
class A {
public:
bool getAB( const int*& a, const int*& b ) const
{
a = _a;
b = _b;
}
protected :
int * a_;
int * b_;
}
Note that the user can still call delete (but not free) on the result of getAB; see this question for more info. If you want to disallow delete, you can replace pointers by smart pointers (e.g. std::unique_ptr).
Actually, if you want your code to be compatible with c++ exceptions, you should never hold two pointers in your class (and rarely, if ever, hold one pointer).
You can indeed protect a little more the internal values, but it will be hard to forbid a delete. Here is the best I could do
class A {
public:
bool getAB( const int ** const a, const int ** const b ) const;
A(int * a, int *b): a_(a), b_(b) {}
protected :
int * a_;
int * b_;
};
bool A::getAB( const int ** const a, const int ** const b ) const
{
*a = a_;
*b = b_;
return true;
}
int main() {
int i=1;
int j=2;
A a(&i, &j);
const int * p1;
const int * p2;
// int * p2; error
a.getAB(&p1, &p2);
// *p1 = 3; error
// delete p1; unfortunately gives no errors
cout << *p1 << " " << *p2 << endl;
return 0;
}
It does require a pointer to const, but delete is unfortunately allowed. And it is not possible to pass a const pointer, because a const pointer has to be immediately initialized.
Consider this
#include <iostream>
class A
{
public:
void fun(int x) const
{
std::cout<<"int x"<<std::endl;
}
void fun(const int x)
{
std::cout<<"const int x"<<std::endl;
}
void fun(int &x)
{
std::cout<<"int &x"<<std::endl;
}
void fun(const int &x)
{
std::cout<<"const int &x"<<std::endl;
}
};
int main()
{
A obj;
int a = 10;
const int b = 10;
int& ref = a;
const int& ref1 = b;
obj.fun(a);
obj.fun(b);
obj.fun(ref);
obj.fun(ref1);
return 0;
}
Compiling this get ambiguities but none of them says its due to fun(const int x) but removing this makes code getting compiled correctly
What difference does it make when we make a argument const ex- fun(const int& x)
and a function itself const ex - fun(int x) const while overload resolution
There are some more doubts trying various combinations, so any generic answer explaining the role of const while overload resolution is welcome
Top level const is ignored on a declaration, so fun(const int x) is same as fun(int x).
Certainly it will conflict with the ref versions and hardly makes any sense. If you hunt for rvalues add fun(int &&x), though its normally used with user defined types
The const after the () qualifies the object instance -- the this pointer. Seleced when you would use const A obj.
I am trying to create a pointer to a member function which has default arguments. When I call through this function pointer, I do not want to specify an argument for the defaulted argument. This is disallowed according to the standard, but I have never before found anything that the standard disallowed that I could not do in some other conformant way. So far, I have not found a way to do this.
Here is code illustrating the problem I'm trying to solve:
class MyObj
{
public:
int foo(const char* val) { return 1; }
int bar(int val = 42) { return 2; }
};
int main()
{
MyObj o;
typedef int(MyObj::*fooptr)(const char*);
fooptr fp = &MyObj::foo;
int r1 = (o.*fp)("Hello, foo.");
typedef int(MyObj::*barptr)(int);
barptr bp1 = &MyObj::bar;
int r2 = (o.*bp1)(); // <-- ERROR: too few arguments for call
typedef int (MyObj::*barptr2)();
barptr2 bp2 = &MyObj::bar; // <-- ERROR: Can't convert from int(MyObj::*)(int) to int(MyObj::*)(void)
int r3 = (o.*bp2)();
return 0;
}
Any ideas on how to do this in conformant C++ if I do not want to specify any values for the defaulted arguments?
EDIT: To clarify the restrictions a bit. I do not want to specify any default arguments either in the call or in any typedef. For example, I do not want to do this:
typedef int(MyObj::*barptr)(int = 5);
...nor do I want to do this:
typedef int(MyObj::*barptr)(int);
...
(o.barptr)(5);
It would be rather strange to expect the function pointers to work the way you expect them to work in your example. "Default argument" is a purely compile-time concept, it is a form of syntactic sugar. Despite the fact that default arguments are specified in the function declaration or definition, they really have nothing to do with the function itself. In reality default arguments are substituted at the point of the call, i.e. they are handled in the context of the caller. From the function's point of view there's no difference between an explicit argument supplied by the user or a default one implicitly supplied by the compiler.
Function pointers, on the other hand, are run-time entities. They are initialized at run time. At run-time default arguments simply don't exist. There's no such concept as "run-time default arguments" in C++.
Some compilers will allow you to specify default arguments in function pointer declaration, as in
void foo(int);
int main() {
void (*pfoo)(int = 42) = foo;
pfoo(); // same as 'pfoo(42)'
}
but this is not standard C++ and this does not appear to be what you are looking for, since you want the "default argument " value to change at run time depending on the function the pointer is pointing to.
As long as you want to stick with genuine function pointers (as opposed to function objects, aka functors) the immediate workaround would be for you to provide a parameter-less version of your function under a different name, as in
class MyObj
{
public:
...
int bar(int val = 42) { return 2; }
int bar_default() { return bar(); }
};
int main()
{
MyObj o;
typedef int (MyObj::*barptr2)();
barptr2 bp2 = &MyObj::bar_default;
int r3 = (o.*bp2)();
return 0;
}
This is, of course, far from elegant.
One can actually argue that what I did above with bar_default could have been implicitly done by the compiler, as a language feature. E.g. given the class definition
class MyObj
{
public:
...
int bar(int val = 42) { return 2; }
...
};
one might expect the compiler to allow the following
int main()
{
MyObj o;
typedef int (MyObj::*barptr2)();
barptr2 bp2 = &MyObj::bar;
int r3 = (o.*bp2)();
return 0;
}
where the pointer initialization would actually force the compiler to implicitly generate an "adapter" function for MyObj::bar (same as bar_default in my previous example), and set bp2 to point to that adaptor instead. However, there's no such feature in C++ language at this time. And to introduce something like that would require more effort than it might seem at the first sight.
Also note that in the last two examples the pointer type is int (MyObj::*)(), which is different from int (MyObj::*)(int). This is actually a question to you (since you tried both in your example): how would you want it to work? With an int (MyObj::*)() pointer? Or with a int (MyObj::*)(int) pointer?
You could create functors instead of function pointers of course.
struct MyFunctor {
int operator() {
return myobj.bar();
}
MyFunctor(MyObj &obj) : myobj(obj) {}
MyObj &myobj;
};
then:
MyFunctor myfunc(o);
myFunctor();
This is not possible given the constraints. Your options are:
Using function wrappers.
Using Functors.
Check out Boost for some handy tools to simplify this.
Task: Suppose you have the following:
class Thing {
public:
void foo (int, double = 3.14) const {std::cout << "Thing::foo(int, double = 3.14) called.\n";}
void goo (int, double = 1.5) const {std::cout << "Thing::goo(int, double = 1.5) called.\n";}
};
void function1 (const Thing& thing, int a, int b, double c) {
// Code A
thing.foo(a,c);
// Code B
thing.foo(b);
// Code C
}
void function2 (const Thing& thing, int a, int b, double c) {
// Code A
thing.goo(a,c);
// Code B
thing.goo(b);
// Code C
}
We want to write a helper function to capture function1 and function2 so that the repeated codes A, B, C need not be written twice.
The following will not compile:
class Thing {
public:
void foo (int, double = 3.14) const {std::cout << "Thing::foo(int, double = 3.14) called.\n";}
void goo (int, double = 1.5) const {std::cout << "Thing::goo(int, double = 1.5) called.\n";}
};
void functionHelper (const Thing& thing, int a, int b, double c, void (Thing::*f)(int, double) const) {
// Code A
(thing.*f)(a,c);
// Code B
// (thing.*f)(b); // Won't compile. Too few arguments passed to (thing.*f), which expects (int, double).
// Code C
}
void function1 (const Thing& thing, int a, int b, double c) {
functionHelper (thing, a, b, c, &Thing::foo);
}
void function2 (const Thing& thing, int a, int b, double c) {
functionHelper (thing, a, b, c, &Thing::goo);
}
First solution (overload of Thing::foo and Thing::goo):
#include <iostream>
class Thing {
public:
void foo (int, double = 3.14) const {std::cout << "Thing::foo(int, double = 3.14) called.\n";}
void foo_default (int a) const {
std::cout << "Thing::foo_default(int) called.\n";
foo(a);
}
void goo (int, double = 1.5) const {std::cout << "Thing::goo(int, double = 1.5) called.\n";}
void goo_default (int a) const {
std::cout << "Thing::goo_default(int) called.\n";
goo(a);
}
};
void functionHelper (const Thing& thing, int a, int b, double c,
void (Thing::*f)(int, double) const, void (Thing::*g)(int) const) {
// Code A
(thing.*f)(a,c);
// Code B
(thing.*g)(b); // This will compile now, since (thing.*g) expects int only as argument.
// Code C
}
void function1 (const Thing& thing, int a, int b, double c) {
functionHelper (thing, a, b, c, &Thing::foo, &Thing::foo_default);
}
void function2 (const Thing& thing, int a, int b, double c) {
functionHelper (thing, a, b, c, &Thing::goo, &Thing::goo_default);
}
int main() {
Thing thing;
function1 (thing, 2, 5, 1.8);
std::cout << '\n';
function2 (thing, 2, 5, 1.8);
}
Output:
Thing::foo(int, double = 3.14) called.
Thing::foo_default(int) called.
Thing::foo(int, double = 3.14) called.
Thing::goo(int, double = 1.5) called.
Thing::goo_default(int) called.
Thing::goo(int, double = 1.5) called.
Second solution (Wrap Thing::foo and Thing::goo into function objects):
#include <iostream>
#include <memory>
class Thing {
public:
void foo (int, double = 3.14) const {std::cout << "Thing::foo(int, double = 3.14) called.\n";}
void goo (int, double = 1.5) const {std::cout << "Thing::goo(int, double = 1.5) called.\n";}
class FooOrGoo {
public:
void operator()(const Thing& thing, int a) const {helper1 (thing, a);}
void operator()(const Thing& thing, int a, double b) {helper2 (thing, a, b);}
virtual ~FooOrGoo() {std::cout << "Thing::FooOrGoo object destroyed.\n";}
private:
virtual void helper1 (const Thing& thing, int a) const = 0;
virtual void helper2 (const Thing& thing, int a, double b) const = 0;
};
class Foo : public FooOrGoo {
virtual void helper1 (const Thing& thing, int a) const override {thing.foo(a);}
virtual void helper2 (const Thing& thing, int a, double b) const override {thing.foo(a, b);}
};
class Goo : public FooOrGoo {
virtual void helper1 (const Thing& thing, int a) const override {thing.goo(a);}
virtual void helper2 (const Thing& thing, int a, double b) const override {thing.goo(a, b);}
};
};
void functionHelper (const Thing& thing, int a, int b, double c, std::unique_ptr<Thing::FooOrGoo> f) {
// Code A
(*f)(thing, a,c);
// Code B
(*f)(thing, b);
// Code C
}
void function1 (const Thing& thing, int a, int b, double c) {
functionHelper (thing, a, b, c, std::unique_ptr<Thing::Foo>(new Thing::Foo)); // 'std::make_unique<Thing::Foo>());' is not supported by GCC 4.8.1.
}
void function2 (const Thing& thing, int a, int b, double c) {
functionHelper (thing, a, b, c, std::unique_ptr<Thing::Goo>(new Thing::Goo)); // 'std::make_unique<Thing::Goo>());' is not supported by GCC 4.8.1.
}
int main() {
Thing thing;
function1 (thing, 2, 5, 1.8);
std::cout << '\n';
function2 (thing, 2, 5, 1.8);
}
Output:
Thing::foo(int, double = 3.14) called.
Thing::foo(int, double = 3.14) called.
Thing::FooOrGoo object destroyed.
Thing::goo(int, double = 1.5) called.
Thing::goo(int, double = 1.5) called.
Thing::FooOrGoo object destroyed.
Which solution do you think is better? I think the second one is more elegant, but there are more lines of code (I couldn't do it without polymorphism).