function overloading and reading fdump-tree-all output [duplicate] - c++

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;
}

Related

C++ template: Derived class cannot resolute Base class function unless using "this->" [duplicate]

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?

Calling const member function in a non-const member function while both of them same function name [duplicate]

This question already has answers here:
How do I remove code duplication between similar const and non-const member functions?
(21 answers)
Closed 2 years ago.
class MyClass {
public:
void Bar()const
{
std::cout << "A::Bar() const\n";
}
void Bar()
{
std::cout << "A::func()\n";
//call Bar()const in here
}
};
I would like to know how i should call Bar()const member function in Bar() member function?
You need to cast the object to a const qualified version to call the const function. That would look like
void Bar()
{
std::cout << "A::func()\n";
const_cast<const MyClass&>(*this).Bar(); // calls const version
}

put together a function pointer and a object [duplicate]

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)...)).

How to declare reference to lambda in C++ [duplicate]

This question already has answers here:
Is auto as a parameter in a regular function a GCC 4.9 extension?
(2 answers)
Closed 5 years ago.
I want to declare a function that takes as argument a function (or lambda) with a specific prototype.
The first try is:
#include <iostream>
using namespace std;
int test(int (&val)(int)) {
return val(2);
}
int main() {
cout << test([](int v){
return v+100;
});
return 0;
}
witch results in error: invalid initialization of non-const reference of type 'int (&)(int)' from an rvalue of type 'main()::<lambda(int)>'
I tried to add const specified to the type but I don't know where exactly so I tried the following that works with GCC (-std=c++14), however I suspect it is illegal since it fails with clang:
int test(const auto& val) {
return val(2);
}
I know I can use template or function pointers or std::function to achieve the same, then please consider this a didactic question. I want to know what does GCC deduce the type of val to, in the second example above (int test(const auto& val)).
template <typename F>
int test(F val) {
return val(2);
}
int test(int val(int)) {
return val(2);
}
int test(std::function<int(int)> val) {
return val(2);
}
I want to declare a function that takes as argument a function (or lambda) with a specific prototype.
Closures generated by lambda expression have a unique and anonymous type. They could also be generic (i.e. template operator()). There is no "easy" way of declaring a function accepting lambdas with a specific prototype. Your best bet is either using a constrained template parameter with something like std::is_invocable or using some sort of type erasure like function_view.
Note: if your lambda is captureless it is implicitly convertible to a function pointer. E.g.
int test(int (*)(int)) { }
test([](int) -> int {}); // OK
test([i = 0](int) -> int {}); // compile-time error
I want to know what does GCC deduce the type of val to, in the second example.
int test(int val(int))
...is equivalent to...
int test(int (*val)(int))
In fact, having both of them in the same scope results in a redefinition error:
int test(int val(int)) {
return val(2);
}
int test(int (*val)(int)) {
return val(2);
}
prog.cc:5:5: error: redefinition of 'test'
int test(int (*val)(int)) {
^
prog.cc:1:5: note: previous definition is here
int test(int val(int)) {
^

What is wrong in this C++ code? Compile error: no matching function for call to ‘Test::Test(Test)’ [duplicate]

This question already has answers here:
Why is the copy-constructor argument const?
(8 answers)
Closed 9 years ago.
#include<iostream>
using namespace std;
class Test
{
/* Class data members */
public:
Test(Test &t) { /* Copy data members from t*/}
Test() { /* Initialize data members */ }
};
Test fun()
{
cout << "fun() Called\n";
Test t;
return t;
}
int main()
{
Test t1;
Test t2 = fun();
return 0;
}
What is wrong with above C++ code? compiler throws following error.
error: no matching function for call to ‘Test::Test(Test)’
You declared a copy constructor which requires a non-const lvalue. However, fun() returns a temporary and you can't bind a temporary to a non-const lvalue. You probably want to declare your copy constructor as
Test(Test const& t) { ... }