Consider having these four functions in one C++ program:
void a(int val)
{
cout<<val;
}
void a(int &val)
{
cout<<val;
}
void a(int *val)
{
cout<<val;
}
void a(double val)
{
cout<<val;
}
Few Questions i have are:
Is there going to be any error in the code? or are they all overloaded without any error.
Can you tell me how to call all of these four functions correctly? My try was below:
int iTmp;
int *pTmp;
double dTmp;
a(iTmp);
a(iTmp);
a(pTmp);
a(dTmp);
The only problem are the functions:
void a(int &val)
and
void a(int val)
The compiler will create the following errors:
Compilation error time: 0 memory: 3140 signal:0
prog.cpp: In function 'int main()':
prog.cpp:28:8: error: call of overloaded 'a(int&)' is ambiguous
a(iTmp);
^
Because he cant distinguish both, if you remove one of them the compilation succeeds
See Example:
#include <iostream>
using namespace std;
void a(int val)
{
cout<<val;
}
void a(int *val)
{
cout<<val;
}
void a(double val)
{
cout<<val;
}
int main() {
int iTmp = 0;
int *pTmp = 0;
double dTmp = 0.0;
a(iTmp);
a(iTmp);
a(pTmp);
a(dTmp);
return 0;
}
See working example:
http://ideone.com/WRZUoW
Your code will compile but calling
int iTmp;
a(iTmp);
will yield an ambiguous overload resolution call since both
void a(int val)
{
cout<<val;
}
void a(int &val)
{
cout<<val;
}
will match.
The reason for this lies in the standard:
[over.match.best]
A viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2)
int->int
int->int&
these are standard conversion sequences and the entire list of [over.ics.rank]p3.2 is checked without success for a better conversion sequence (exact match in both cases)
They are thus deemed "undistinguishable".
A word of advice: the variable are also not initialized and (if automatic variables) even if your code compiled, the output would be undefined.
The compiler must be able to know what function to call.
With
int i = 12;
a(i);
both a(int i) and c(int& i) are acceptable candidates and compiler throws an error.
and
void a(const int& i) { ... }
will suffer from same problem.
These two function will cause issues
void a(int val)
{
cout<<val;
}
void a(int &val)
{
cout<<val;
}
Your call a(iTmp); have two possible candidates. Compiler should shown an error for these. Otherwise pointer argument(int *val)and double argument(double val) are okay.
The most obvious problem is that
void a(int val) {
and
void a(int& val) {
are ambiguous when called with iTmp.
Aside from that, depending on whether the variables are global or local ones, the code is using uninitialized variables -> UB and whether or not,
void a(int* val) {
std::cout << val << std::endl;
}
is overloaded correctly is up for debate. I'd assume that it should be std::cout << *val << std::endl;, but that of course depends on what the function is supposed to do (although a function that prints an address would usually be parameterized by (void* or char*);
Related
I am new to C++ and this might sound very basic. The compiler always looks at the method that returns a const pixel value for me, which I do not want it to bc I want to change the value of the returned pixel. This situation does not happen during my previous assignments but it happens this time. Is there any way to resolve this? Thank you so much.
provided PNG class:
const HSLAPixel & getPixel(unsigned int x, unsigned int y) const;
HSLAPixel & getPixel(unsigned int x, unsigned int y);
my code:
HSLAPixel & original = png_.getPixel((*it).x, (*it).y);
They aren't quite the same. One is declared const. The other one is non-const. The compiler will use the const version when your PNG is marked const and the non-const version otherwise.
I did this:
#include <iostream>
class Foo {
public:
void foo(int i) const { std::cout << "Const version.\n"; }
void foo(int i) { std::cout << "Non-const version.\n"; }
void myFunction() const { foo(10); }
};
int main() {
Foo foo;
foo.foo(10);
foo.myFunction();
}
When I run it, the first call to foo() prints the Non-const message, and the second one prints the const message.
I need explanation about why the following code does not compile. I have a workaround which I will articulate below, but I don't understand the failure of the original version.
To speed up code reading: The concept is to define an interface (ISomething), then to create an abstract implementation (ASomething) which implements the second function (2) using the first (not yet defined) one (1). A complete implementation which derives from the abstract one (for example SomethingImpl) must define the first method and has the option to override the second one.
#include <iostream>
class ISomething
{
public:
virtual ~ISomething()
{ }
virtual int f(int x) = 0; // (1)
virtual int f(int x, int y) = 0; // (2)
};
class ASomething
: public virtual ISomething
{
public:
virtual int f(int x, int y) // (2)
{
return f(x) + f(y); // (3)
}
};
class SomethingImpl
: public ASomething
{
public:
virtual int f(int x) // (1)
{
return x+1;
}
};
int main()
{
SomethingImpl a;
std::cout << a.f(10) << std::endl; // (1)
std::cout << a.f(10,20) << std::endl; // (2)
return 0;
}
Compiling this code gives error on both Visual Studio 2013 (Windows) and g++ 4.4.5 (Linux). The errors are very similar, I will detail the g++ output only:
$ g++ SibFun.cpp -o SibFun
SibFun.cpp: In member function ‘virtual int ASomething::f(int, int)’:
SibFun.cpp:18: error: no matching function for call to ‘ASomething::f(int&)’
SibFun.cpp:16: note: candidates are: virtual int ASomething::f(int, int)
SibFun.cpp:18: error: no matching function for call to ‘ASomething::f(int&)’
SibFun.cpp:16: note: candidates are: virtual int ASomething::f(int, int)
SibFun.cpp: In function ‘int main()’:
SibFun.cpp:36: error: no matching function for call to ‘SomethingImpl::f(int, int)’
SibFun.cpp:26: note: candidates are: virtual int SomethingImpl::f(int)
make: *** [SibFun] Error 1
I tried to use different notation at (3) like return this->f(x) + this->f(y), but I experienced no significant change in the error message.
However when I changed (3) to return ISomething::f(x) + ISomething::f(y); I only got:
$ g++ SibFun.cpp -o SibFun
SibFun.cpp: In function ‘int main()’:
SibFun.cpp:36: error: no matching function for call to ‘SomethingImpl::f(int, int)’
SibFun.cpp:26: note: candidates are: virtual int SomethingImpl::f(int)
make: *** [SibFun] Error 1
But! When change (2) from f to g all compiles and runs as expected.
What is the reason behind this begavior? Why can't I use the f name for (2)?
Function overloading works only for functions visible in the same scope:
class ASomething
: public virtual ISomething
{
public:
virtual int f(int x, int y) // (2)
{
return f(x) + f(y); // (3)
}
using ISomething::f;
//~~~~~~~~~~~~~~~~~^
};
class SomethingImpl
: public ASomething
{
public:
virtual int f(int x) // (1)
{
return x+1;
}
using ASomething::f;
//~~~~~~~~~~~~~~~~~^
};
Both compilation failures happen for the same reason. While you're overriding one virtual member function, you're hiding the other. In ASomething:
virtual int f(int x, int y) // (2)
{
return f(x) + f(y); // (3)
}
Name lookup on f finds ASomething::f and stops, it doesn't keep going to look for other overloads. Since ASomething::f takes two arguments, and you're trying to call it with one, error. In order to allow for overloading against the base class, you have to introduce the base class member functions with a using-declaration:
using ISomething::f; // NOW, ISomething::f(int ) is found by lookup
virtual int f(int x, int y)
{
return f(x) + f(y);
}
And similarly, SomethingImpl needs a using ASomething::f; statement so that a.f(10) can compile.
The problem is not an 'overloading' problem, but hiding a base class function (See other answers)
A slightly modified example:
#include <iostream>
class ISomething
{
public:
virtual ~ISomething() {}
virtual int f(int x) = 0; // (1)
virtual int f(int x, int y) = 0; // (2)
};
class ASomething: public virtual ISomething
{
public:
virtual int f(int x, int y) // (2)
{
// `this->f(x)` fails:
ISomething& i = *this;
return i.f(x) + i.f(y); // (3)
}
};
class SomethingImpl: public ASomething
{
public:
virtual int f(int x) // (1)
{
return x+1;
}
};
int main()
{
SomethingImpl a;
// `a.f(10, 20)` fails:
ISomething& i = a;
std::cout << i.f(10) << std::endl; // (1)
std::cout << i.f(10, 20) << std::endl; // (2)
return 0;
}
Hence, calling f from the interface, resolves the conflict. Although, you should consider using base::f, as suggested in other answers.
C# allows to mark function argument as output only:
void func(out int i)
{
i = 44;
}
Is it possible to do something similar in C/C++? This could improve optimization. Additionally is should silence out warnings "error: 'myVar' may be used uninitialized in this function", when variable is not initialized and then passed to function as output argument.
I use gcc/g++ (currently 4.4.7) to compile my code.
Edit: I know about pointers and references, this is not what I am looking for. I need something like this:
void func(int* __attribute__((out)) i)
{
*i = 44;
}
void func2()
{
int myVal; // gcc will print warning: 'myVar' may be used uninitialized in this function
func(&myVal);
//...
}
Edit 2: Some extra code is needed to reproduce warning "'myVar' may be used uninitialized in this function". Additionally you have to pass -Wall -O1 to gcc.
void __attribute__((const)) func(int* i)
{
*i = 44;
}
int func2()
{
int myVal; // warning here
func(&myVal);
return myVal;
}
"Is it possible to do something similar in C/C++?"
Not really. Standard c++ or c doesn't support such thing like a output only parameter.
In c++ you can use a reference parameter to get in/out semantics:
void func(int& i) {
// ^
i = 44;
}
For c you need a pointer, to do the same:
void func(int* i) {
// ^
*i = 44;
// ^
}
Note that there are no distinctions between out and in&out parameters, unless you use a const reference (which means input only):
void func(const int& i) {
// ^^^^^
i = 44;
}
When you want to pass an arg as output in C++ you pass it as a reference :
void func(int &i)
{
i = 44;
}
and you must initialize it before doing anything on it.
Note :
You can specify when you want the arg to be just an input with a const ref :
void func(const int &i)
{
i = 44;
}
I have a bit of code and I have 3 overloaded functions. I want one of them to accept a double as a parameter or to be called if there are no passed arguments. The others accept only an int and the other a char, that's it. How would I go about doing that?
If you want a function to execute when users make a call with no parameters, give your parameter a default:
void foo(double d = 0.0) {
...
}
void foo(int i) {
...
}
void foo(char c) {
...
}
When users call foo(), the overload taking double will be called. The code would be executed as if zero has been passed.
Check this code:
#include <iostream>
using namespace std;
void foo(double x=0.0) // give it a default value for it to be called with no arguments
{
cout<<"foo(double) is being called"<<endl;
}
void foo(int x)
{
cout<<"foo(int) is being called"<<endl;
}
void foo(char x)
{
cout<<"foo(char) is being called"<<endl;
}
int main()
{
foo();
foo(3.5);
foo(10);
foo('c');
return 0;
}
Output:
foo(double) is being called
foo(double) is being called
foo(int) is being called
foo(char) is being called
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";
}