invalid user-defined conversion - c++

please have a look at this program and the error it is generating:
#include <iostream>
using namespace std;
class A
{
public:
virtual void f(){}
int i;
};
class B : public A
{
public:
B(int i_){i = i_;} //needed
B(){} //needed
void f(){}
};
int main()
{
//these two lines are fixed(needed)
B b;
A & a = b;
//Assignment 1 works
B b1(2);
b = b1;
//But Assignment 2 doesn't works
B b2();
b = b2; // <-- error
}
upon compilation, I get the following error:
$ g++ inher2.cpp
inher2.cpp: In function ‘int main()’:
inher2.cpp:32:10: error: invalid user-defined conversion from ‘B()’ to ‘const B&’ [-fpermissive]
inher2.cpp:14:6: note: candidate is: B::B(int) <near match>
inher2.cpp:14:6: note: no known conversion for argument 1 from ‘B()’ to ‘int’
inher2.cpp:32:10: error: invalid conversion from ‘B (*)()’ to ‘int’ [-fpermissive]
inher2.cpp:14:6: error: initializing argument 1 of ‘B::B(int)’ [-fpermissive]
Can you help me find the problem? thank you

Your "B b2();" is the 'vexing parse' problem of C++ (see here - the 'most vexing parse' takes the ambiguous syntax further).
It looks to the C++ compiler that you are declaring a function (a pre-declaration).
Check it out:
int foo(); //A function named 'foo' that takes zero parameters and returns an int.
B b2(); //A function named 'b2' that takes zero parameters and returns a 'B'.
When you later do:
b = b2;
It looks like you are trying to assign a function (b2) to a variable (b).
To call a constructor with zero parameters, call it without the parentheses and you'll be fine:
B b2;
For more information, see:
Understanding 'most vexing parse' - why allow ambiguous syntax?
Most vexing parse: why doesn't A a(()); work?

B b2();
It is a function declaration, not a variable declaration!
The function name is b2 which takes no argument, and returns object of type B.
Search for vexing parse in C++.

Related

Aggregate constexpr default contructor error with partial NSDMI

I have a simple structure below which is used in constant expressions with aggregate initialization syntax. Now, I would like to make test::c optional thanks to NSDMI but this triggers an error for the default constructor in constant expression context with gcc and clang.
I don't understand why implicit default constructor default-initializes all members in first case but not with NSDMI.
There is no error if I set default value to all members but this is not what I want.
Moreover, I cannot declare a default constructor because the structure will no longer be an aggregate.
How the default contructor is implicitly generated in both case ? Is there a standard rule ?
Is there a way to fix the error and conserve the warning [-Wmissing-field-initializers] ?
#include "debug.h"
struct test {
//OK
/* int a, b, c; */
/* int a=0, b=0, c=3; */
//ERROR
int a, b, c=3;
};
int main(){
const test val1 = test(); //{0,0,3}
constexpr test val2 = test(); //error: call to non-'constexpr' function 'test::test()'
constexpr test val3 = {}; //{0,0,3}
constexpr test val4 = {1}; //warning: missing initializer for member 'test::b'
constexpr test val5 = {1,2}; //{1,2,3}
}
Output :
test.cpp: In function 'int main()':
test.cpp:13:32: error: call to non-'constexpr' function 'test::test()'
constexpr test val2 = test();
^
test.cpp:3:8: note: 'test::test()' is not usable as a 'constexpr' function because:
struct test {
^~~~
test.cpp:8:9: note: defaulted default constructor does not initialize 'int test::a'
int a, b, c=3;
^
test.cpp:8:12: note: defaulted default constructor does not initialize 'int test::b'
int a, b, c=3;
^
test.cpp:15:29: warning: missing initializer for member 'test::b' [-Wmissing-field-initializers]
constexpr test val4 = {1};
^
Thank you for your help.

Passing a function as a template arguments

I am trying to pass a function as an argument to a template class - the objective is that then I can pass any function as a argument and achieve different functionality:
int A()
{
return 0;
}
void Test() {
auto B2 = B<int(*A)()>(&A);
}
int main()
{
Test();
}
But I am getting compilation issue:
$ c++ -std=c++14 try.cpp
try.cpp: In function 'void Test()':
error: cast from 'int (*)()' to 'int' loses precision [-fpermissive]
auto B2 = B<int(*A)()>(&A);
^ ^
How can I instantiate class B with a function of any return type and accepting any argument and resolve the compilation?
You should remove the function name A in the template parameter in the line auto B2 = ... such that it looks like this:
auto B2 = B<int(*)()>(A);
The name is not a part of the type specifier, and the type is the only thing the compiler looks for when trying to instantiate the class template. You can use this snippet to refer to the name of the function and let the compiler deduce its type:
auto B2 = B<decltype(&A)>(A);
Note that you can optionally drop the & before A when passing it to the constructor of B (doesn't work for decltype(&A) though), as it's implicitly converted to a function pointer.
Function name is not part of the type of a function pointer.
This line:
auto B2 = B<int(*A)()>(&A);
should be:
auto B2 = B<int(*)()>(&A);

Error calling the constructor

I'm a little new with OOP and I have a small problem with a constructor inside of a derived class.
I have the following code:
class Functionar{
protected:
char nume[20];
int cnp;
public:
Functionar(char *n,int c){strcpy(nume,n); cnp=c;}
virtual void Afisare();
};
void Functionar::Afisare()
{
cout<<"Nume: "<<nume<<endl<<"CNP: "<<cnp<<endl;
}
class Permanent:public Functionar{
protected:
int salariu;
int nrorelucrate;
public:
//Permanent(char *n,int c,int s,int nr): Functionar(char *n,int c),salariu(s),nrorelucrate(nr){}
Permanent(char *n,int c,int s,int nr)
{
Functionar(char *n,int c);
salariu=s;
nrorelucrate=nr;
}
//void Afisare();
};
main()
{
Functionar Claudiu("Claudiu",495);
Claudiu.Afisare();
}
Sorry for the variable and function names. They might look a little strange. The idea is that I want to create a constructor in the derived class using the base constructor for nume and cnp.
I have a couple of errors:
In constructor 'Permanent::Permanent(char*, int, int, int)':
[Error] no matching function for call to 'Functionar::Functionar()'
[Note] candidates are:
[Note] Functionar::Functionar(char*, int)
[Note] candidate expects 2 arguments, 0 provided
[Note] Functionar::Functionar(const Functionar&)
[Note] candidate expects 1 argument, 0 provided
[Error] expected primary-expression before '(' token
[Error] expected primary-expression before 'char'
[Error] expected primary-expression before 'int'
C:\Users\Stefan\Desktop\Probleme Culegere POO\problema12.cpp In function 'int main()':
[Warning] deprecated conversion from string constant to 'char*' [-Wwrite-strings]
I don't understand why there is no matching for 'Functionar::Functionar()'. Thank you.
Use
Permanent(char *n,int c,int s,int nr) :
Functionar(n,c)
//your other variables go here
{
}
Without the initializer list, a default constructor is required because the class attempts to default-initialize the its base.
Even if you did have a default constructor for Functionar, your version would just create a temporary object that would get destroyed after the ; and not initialize the base as you would expect.
You should use a constructor's initializer list to call constructor of the base class(especially for ctors with arguments), such as:
Permanent(char *n, int c, int s, int nr) : Functionar(n, c), salariu(s), nrorelucrate(nr) {}

c++: no matching function call, particularly it is declared as parameter type unmatching

g++ compiler complains about:
error: no matching function for call to ‘AddressSpace::resolve(ClassOne&, ClassTwo*&, ClassThree&) const’
note: candidates are: bool AddressSpace::resolve(ClassOne&, ClassTwo*, ClassThreer) <near match>
The code causing this error is
void Class::handler(ClassOne& objOne, ClassTwo& objTwo,
ClassThreer objThree) {
obj.getAddressSpaceObj().resolve(objOne, objTwo.pointer, objThree);
}
I digged into the code and found this error is caused by the reference type returned by getOtherObj() . I make it to return a const reference to the AddressSpace object in the class definition, see
const AddressSpace &getAddressSpaceObj(){
return addressSpace;
}
After I change this definition to return a normal reference,
AddressSpace &getAddressSpaceObj(){
return addressSpace;
}
the compiler doesn't complain about it any more. I wonder why this error is declared as parameter mismatching error? Why compiler didn't copy content as the parameters of function call but passed them as references?
If resolve does not have a const specifier then you can not call it on a const reference, so that would be consistent with changing it to be being non-const and having it now work. Here is a really trivial example:
#include <iostream>
class A
{
public:
void someFuncA() {};
void someFuncB() const {} ;
} ;
int main()
{
A
a1 ;
const A &aRef = a1 ;
a1.someFuncA() ;
// Below won't work because aRef is a const & but someFuncA() not const
//aRef.someFuncA() ;
// Below will work since someFuncB() is const
aRef.someFuncB() ;
}
Just for completeness sake, if you uncomment aRef.someFuncA() then the error you will receive will be similar to this:
19:19: error: no matching function for call to 'A::someFuncA() const'
19:19: note: candidate is:
6:12: note: void A::someFuncA() <near match>

Deciphering a function overload not found error message

I have the following code :-
class A : public B {
public:
_container (B* b) {
container_ = b;
}
private:
B* container_;
};
void foo(const A& a, const B& b) {
A new_a (a);
new_a._container(&b);
}
If I try to compile this using icpc12, I get :-
error: no instance of overloaded function "A::_container" matches the argument list
argument types are: (const B *)
object type is: A
new_a._container (&b);
Now, I understand that the first line of the error means there is some sort of type mismatch between the function being called and the function definitions available and I'm trying to narrow down the problem using the other two lines of the error message.
What do the second and third lines mean?
The function takes a non-const pointer as an argument, and you're passing a const pointer.