class Bar { operator Foo(); } - c++

What does this style of operator overloading mean?
class Foo {
Foo(int a) { ... }
};
class Bar {
operator Foo() { return Foo(25); }
};

That is user-defined conversion function which converts an instance of Bar into Foo implicitly.
Bar bar;
Foo foo = bar; // bar implicitly converts into Foo.
It is as if you've written this:
Foo foo = Foo(25);
If you've such a conversion function, then you can call this:
void f(Foo foo); //a function which accepts Foo
f(bar); // bar implicitly converts into Foo.
So such implicit conversion may not be desirable sometime, as it might cause problem, producing unintended result. To avoid that, you can make the conversion function explicit as (in C++11 only):
//valid in C++11 only
class Bar {
explicit operator Foo() { return Foo(25); }
};
Now both of these would give error:
Foo foo = bar; //error
f(bar); //error
However, the following is allowed:
Foo foo = static_cast<Foo>(bar); //Ok
f(static_cast<Foo>(bar)); //Ok

It's an overload of the cast operator. Best documentation I could find was MSDN
Basically, if you have a Bar you can cast it to a Foo which is constructed with a specific value:
Bar b;
Foo f = b;

Related

Why does `std::function` can accept pointer to member function while the first param of `Args...` is passed by value?

Suppose we have a class Foo as follows:
struct Foo
{
int x = 100;
void print()
{
std::cout << x << std::endl;
}
};
Obviously we can use std::function to wrap Foo::print as follows:
std::function<void(Foo*)> f(&Foo::print);
Foo bar;
f(&bar); // Output 100
// or
std::function<void(Foo&)> f(&Foo::print);
Foo bar;
f(bar); // Output 100
But once I found that use std::function<void(Foo)> instead of std::function<void(Foo*)> or std::function<void(Foo&)> still works:
// Neither Foo& nor Foo*
std::function<void(Foo)> f(&Foo::print);
Foo bar;
f(bar); // Still output 100
Why does the last one works?
Member functions require a specific class object to invoke, and void(Foo) is just a function type that accepts a copy of the Foo class.
So f(bar) will copy bar and invoke the print() member function of its copy. If Foo is not copyable then it won't work.

Passing functions as arguments not working inside a class

Creating a Foo object passing func to constructor works just fine in this example:
int func(int a) { return a; }
struct Foo {
Foo( int (*func_ptr)(int) ) {};
};
Foo bar(func);
However attempting to create a Foo object inside another class does not:
class ThisIsCrap {
Foo doesntWork(func);
};
How can I create a Foo object inside a class like I can outside a class? On the bit that doesn't compile, the error is: "cannot resolve type 'func'"
Thanks in advance.
You can provide an initializer for non-static class data members with a default member initializer (DMI):
int func(int a) { return a; }
struct Foo { Foo(int (*)(int)) {}; };
class ThisIsGreat {
Foo one_way = func; // DMI with copy-initialization syntax
Foo another_way{func}; // DMI with list-initialization syntax
};
Or of course you could use a constructor:
class ThisIsSane {
ThisIsSane()
: third_way(func) // constructor-initializer list
{}
Foo third_way;
};
Language-lawyer note for pedants: In C++11, ThisIsGreat is not an aggregate; in C++14 it is.
1,000 thanks to Kerrek SB.
class ThisWorks {
Foo* working;
ThisWorks() {
working = new Foo(func);
}
}

Default initialize data members that are objects?

Why do you have to initialize object data members in the constructor and you can't default initialize them like with primitive types? Is it possible to initialize them like with primitive types?
Here's an example:
class foo {
int a;
public:
foo(int _a) :a(_a) {};
};
class bar {
string a = "asdf";//no error
int num = 1;//no error
foo x(1); //error, why?
foo z;
public:
bar(): z(1){}//no error
};
In-class initializers only work with the operator= syntax or with brace-initializer lists, not with the function style initialization. So
foo x{1};
instead of
foo x(1);
should do the trick.
In your case, you could also use
foo x = 1;
but that would break if foo's constructor taking a single int was explicit.
Permitting direct-initialization in class-definition would lead to difficulties in distinguishing from function declarations:
Consider:
struct k;
struct foo { foo(int x = 1){} };
class toto
{
static constexpr int k = 1;
foo x(1); // hm might be ok...
foo y(); // hm ... NOK , what y is ? an object or a function declaration?!?!
foo z(k); // problem .... this seems a fucntion definition?!!!
foo z{k}; // clear it is not a function definition
};
The proper way to do this is either:
foo f= 1;
or
foo f{1};
or
foo f = {1};

Calling a constructor with no parameters works, with a parameter doesn't. Why?

I have a class defined as follows:
class Foo {
private:
boolean feature;
public:
Foo(boolean feature) : feature(feature) {}
// ...
};
I'm trying to construct an instance, as a private property of another class:
class Bar {
private:
Foo foo(true);
// ...
};
This doesn't work. I get expected identifier before numeric constant on the line with the declaration. When I remove the parameter from Foo's constructor definition simply and ask for a Foo foo;, it works.
Why?
How do I define and declare an instance of Foo that takes a boolean parameter?
You can't use that initialisation syntax in a class member declaration; you can only initialise members with {} or =. The following should work (assuming support for C++11 or later):
Foo foo{true};
Foo foo = Foo(true);
The pre-C++11 way to do this is:
class Bar {
public:
Bar() : foo(true){} //initialization
private:
Foo foo; //no parameter
};
Bonus:
class Bar {
private:
Foo foo(); //<- This is a function declaration for a function
//named foo that takes no parameters returning a Foo.
//There is no Foo object declared here!
};

"Ambiguous call to overloaded function"

I have a structure like this, with struct Baz inheriting from 2 different structs, Foo and Bar.
I have 2 methods called the same thing, one with a parameter of Foo and one with a parameter of Baz.
struct Foo
{
};
struct Bar
{
};
struct Baz : Foo, Bar
{
virtual void something(const Foo& foo)
{
};
virtual void something(const Bar& bar)
{
};
};
I call it like this
Baz baz;
baz.something(baz);
And understandably I have an issue with my code knowing which function I am calling if I pass it an instance of Baz. I get “Ambiguous call to overloaded function”.
I know I can cast my Baz to Foo or Bar to resolve the issue...
Baz baz;
baz.something((Bar)baz);
...but is there another way of dealing with this design issue?
I want to call the Foo method ONLY if the object being passed is not of type Bar.
edit:
If this was C# (which it isn't) I could probably solve this using a template where clause.
First off, note that the cast you've used would create a temporary object. You probably meant this:
baz.something(static_cast<Bar&>(baz));
And to answer your question, it should be possible to use SFINAE for this:
struct Baz : Foo, Bar
{
virtual void something(const Bar &bar)
{ /* ... */ }
template <
class T,
class = typename std::enable_if<
std::is_convertible<const T&, const Foo&>::value &&
!std::is_convertible<const T&, const Bar&>::value
>::type
>
void something (const T &foo)
{ something_impl(static_cast<const Foo&>(foo)); }
private:
virtual void something_impl(const Foo &foo)
{ /* ... */ }
};
Live example