I'm new to C++, and am used to working with Java.
In Java, I have the option of declaring an object without instantiating it, and would like to do the same in C++.
Assuming there is some class Foo, in Java I could write Foo bar; to declare an instance of Foo without initializing bar.
However, in C++ when I write Foo bar;, bar is initialized by calling the default constructor of class Foo.
This is particularly vexing if I have written one or more constructors for class Foo, each of which have at least one argument. In this case, the code will fail to compile with an error similar to no matching function for call to 'Foo::Foo()'
For example, say I have the following class definition in Java:
public class Foo {
private boolean b;
Foo(boolean b) { this.b = b; }
}
and the corresponding class definition in C++:
class Foo {
bool b_;
public:
Foo(bool b) : b_(b) {}
};
In Java, I could write some method
public static Foo makeFoo(int x) {
Foo result;
if (x > 10) { result = new Foo(true); }
else { result = new Foo(false); }
return result;
}
However, if I write a similar method in C++, I get a compilation error:
Foo makeFoo(int x) {
Foo result; // here, a call is made to Foo::Foo() which doesn't exist, and thus compilation fails
if (x > 10) {
result = Foo(true); // this would probably also fail since I didn't specify a copy-constructor, but I'm not entirely sure
}
else {
result = Foo(false); // as above, I think this would probably fail
}
return result;
}
While the example I gave is useless, I frequently used this sort of approach when writing Java code.
Is there a way to emulate this behavior in C++?
Alternatively, is this just bad design? If so, what sort of approach would you recommend?
If you don't want to use pointers to get reference functionality as Igor (and others) explained in the first comment on your question, then you can do a couple of things.
First, the philosophy of value types instead of reference types is do not create them until you need them. Your temptation to declare the reference ahead of using the object to obtain a sort of polymorphic functionality in the remainder of the function (some post-create common init code, perhaps) is reasonable design, but cannot be expressed the way you wrote it because it would involve creating a value.
You could provide a default constructor and give it some behaviour -- but it's pretty clear that neither you nor anybody else want to be coerced into doing that.
The essence of the alternative is to move the variable inside the scope and return it.
Foo makeFoo(int x) {
if (x > 10) {
Foo result = Foo(true);
return result;
}
else {
Foo result = Foo(false);
return result;
}
}
Obviously this prevents you from writing common post-create init code after the if block before the return. To do that, you would write the if block in its own function and have it return the result, then write the follow up code after you've initialized your object.
Foo premakeFoo(int x) {
if (x > 10) {
Foo result = Foo(true);
return result;
}
else {
Foo result = Foo(false);
return result;
}
}
Foo makeFoo(int x) {
Foo result = premakeFoo(x);
// common post init code can go here.
return result;
}
If you don't want it in a completely separate function, you could do a lambda.
Foo makeFoo(int x) {
Foo result = ([=]() {
if (x > 10) {
Foo result = Foo(true);
return result;
} else {
Foo result = Foo(false);
return result;
}
})();
// common post init code can go here.
return result;
}
Or in your case, if it's small, use a ternary expression inline.
Foo makeFoo(int x) {
Foo result = (x > 10) ? Foo(true) : Foo(false); // or just Foo(x>10)
// common post init code can go here.
return result;
}
There are other clever options involving templates, but they all revolve around the idea of isolating the different expressions for the overloaded constructors and then using an assignment to initialize a variable given some more sophisticated expression. And what you are trying to do is to get the expression that constructs the value in two different ways to span a scope block (span the if blocks). Ternaries and functions are the options here for getting the if logic executed within a single expression.
In Java when you do Foo result; you create a reference to Foo, you don't actually create an object. C++ is different though since it has value semantics and Foo result; actually creates an object. If there is no default constructor, then an error is raised.
To get the same type of behavior you need to use pointers in C++. You can't use a reference since a reference needs to be bound to an object when it is created, unlike Java. So, if you use a std::unique_ptr<Foo> you can declare that, and then initialize it later with a std::unique_ptr<Foo> that you initialize in your creation logic. Using your example, the code would look like
Foo makeFoo(int x) {
std::unique_ptr<Foo> result; // here result doesn't have an actual object yet
if (x > 10) {
result = std::make_unique<Foo>(true); // now we pass the values we want to construct with and get a valid object
}
else {
result = std::make_unique<Foo>(false); // same as above
}
return *result; // this lets you return a `Foo` which will be a copy, and the Foo created by make_unique will be destroyed
}
If you don't want to make a copy, you can use return result; instead, and change the function to return a std::unique_ptr<Foo>.
what you are trying to do is called a factory pattern and is usually implemented in this way
std::unique_ptr<Foo> makeFoo(int x) {
std::unique_ptr<Foo> result = nullptr;
if (x > 10) {
result = std::make_unique<Foo>(true);
}
else {
result = std::make_unique<Foo>(false);
}
return result;
}
for the above to work you also need to include the header. refer to this for further information on unique_ptr and memory management in c++
also, note I would not recommend this level of verbosity in code, I wrote that out for presentation purposes. The following version offers fewer lines of code and is more elegant.
std::unique_ptr<Foo> makeFoo(int x) {
if (x > 10) {
return std::make_unique<Foo>(true);
}
return std::make_unique<Foo>(false);
}
Related
I was wondering if there's an elegant solution for the following issue:
Let's say I'd like to have a variable holding a value with a pretty complex type and would the compiler to automatically infer it's type, but declare first and give value later in the code because of initialization in an if statement.
For example:
{
auto a;
if (some predicate)
a = init_a(1);
else
a = init_a(2);
}
Obviously this code doesn't compile, but the I think that the compiler has all the information it needs to infer the type.
If 'a' was just an int, this was not a problem, but if the type is a complex template, I don't want to have to write it (or in some cases even know it).
Also, i wouldn't want to call the default constructor of a and then write over it.
Possible solutions:
Template the type of 'a'.
initialize 'a' using a lambda and move the predicate into the lambda.
Just write the type of 'a' instead auto.
Use a void pointer/shared_ptr and then init 'a' on the heap.
Each of these has its own drawbacks.
Is there a more elegant solution for it?
The compiler doesn't have infinite lookahead what is happening further on in the code. It only knows what's happening at the current statement. Therefore it can't deduce any types without an initializer.
If you don't know the return-type of init_a then you could use decltype:
decltype(init_a(1)) a;
You can also use a lambda call to initialize the variable:
auto a = [ /* Captures needed for the condition... */ ]()
{
if (some_condition)
return init_a(1);
else
return init_a(2);
}(); // Call the lambda immediately
Or, as mentioned in many comments, use the ternary conditional expression:
auto a = some_condition ? init_a(1) : init_a(2);
There's a technique called "Immediately Invoked Lambda Expression" that is using lambda to initialize a variable in a complex way. Using this approach your a can be const which improves const-correctness. More details here.
For a simple binary predicate, consider just using the ternary operator:
struct A { int a; };
A initA(int a) { return A{a}; }
bool somePredicate(int input) { return input == 42; }
int main() {
const auto input = 42;
const auto a = somePredicate(input) ? initA(1) : initA(2);
}
for more complex initialization logic (beyond a binary case), wrap the initialization logic in a lambda:
struct A { int a; };
A initA(int a) { return A{a}; }
bool somePredicate(int input) { return input == 42; }
int main() {
const auto input = 42;
const auto a = []() {
if (somePredicate(input)) { return initA(1); }
else if (input == 100) { return initA(100); }
else { return initA(2); }}();
}
Both these approaches come with additional possibility of making the variable to be initialized const.
If the return types of your lambda are different but convertible to some type then you can force the return type (note the -> is mandatory when specifying a return type):
auto a = [=]() -> ConvertedType {
if (some_predicate) {
return CovertibleType1(1);
} else if (other_predicate) {
return ConvertibleType2(2);
}
return ConvertibleType3(3);
}();
Though I realize this basically defeats the auto declaration...
I know that one can implement functions with optional parameters like so:
int someFunction(int A, int B = -1) {
if (B != -1) {
... // If B given then do something
} else {
... // If B not given then do something else
}
}
However, I'd lake to take advantage of std::optional as recommended by a coworker. Here's what I'm trying to do but I'm getting errors:
int some Function(int A, std::optional<int> B) {
if (B.has_value()) {
... // If B given then do something
} else {
... // If B not given then do something else
}
}
The problem is that in the first approach, I can call the function like so someFunction(5) and C++ will realize I've opted not to use the optional parameter. But in the second aproach calling someFunction(5) in the same way will produce the error too few arguments to function call.
I want to be able to call the function without including the optional argument with the second approach, is this possible/recommended?
To use it in the way you intend here, I believe you'd need to specify a default value of std::nullopt:
int some Function(int A, std::optional<int> B = std::nullopt) {
if (B.has_value()) {
... // If B given then do something
} else {
... // If B not given then do something else
}
}
It doesn't really make sense; the normal solution would be an additional overload int some Function(int A).
As I am beginning to take advantage of the C++17 structured bindings and if operator init statements for more elegant function result reporting and checking, I started doing the following, if accordance with C++ Core Guideline F21:
std::pair<bool, int>Foo()
{
return {true, 42}; //true means that function complete with no error and that 42 is a good value
}
void main(void)
{
if (auto [Result, Value] = Foo(); Result)
{
//Do something with the return value here
}
}
Then, of course, I though that it would be nice to have a reusable template for such return types so that nobody has to duplicate bool portion of the pair:
template <typename T> using validated = std::pair<bool,T>;
validated<int> Foo()
{
return {true, 42};
}
void main(void)
{
if (auto [Result, Value] = Foo(); Result)
{
//Do something with the return value here
}
}
This works great for me, but now I am wondering if there is some sort of standard equivalent of this template so that I don't have to reinvent the wheel and define it myself. Seems like an arbitrary type value coupled with a validity flag would be a useful construct, but I could not find anything in standard library. Am I missing something?
std::optional is exactly what you are asking about. It's even in the description:
A common use case for optional is the return value of a function that may fail. As opposed to other approaches, such as std::pair<T,bool>, optional handles expensive-to-construct objects well and is more readable, as the intent is expressed explicitly.
The if from the example would look a bit more straightforward:
#include <optional>
#include <iostream>
std::optional<int> Foo(bool fail)
{
if (!fail) return {42};
return {};
}
void process(bool fail) {
if (auto val = Foo(fail)) {
std::cout << val.value() << '\n';
} else {
std::cout << "No value!\n";
}
}
int main() {
std::optional<int> oi;
process(true);
process(false);
}
If you really wished to use Value explicitly then you can always unpack it via reference on a successful branch i.e. auto Value = val.value();
You need to beware of some caveats. 2 from the top of my head:
Performance: Why is the construction of std::optional<int> more expensive than a std::pair<int, bool>? although for the given example up-to-date clang with -O3 looks pretty convicing
Note: static was added for process for brevity - to prevent generation of version for external linking.
It will return false if object was default constructed. That might surprise some, default construction of optional doesn't default construct underlying value.
EDIT:
After the comments I decided to explicitly state that there isn't anything like type alias for pair<T,bool> or similar compatible with standard library. It's not easy to prove something does not exist, but if there would such a type the standard library would most certainly used it in declaration of insert, it doesn't; hence, I strongly imply that there isn't any semantic wrapper around it.
You might be interested in the proposed std::expected.
Its interface follows std::optional pretty closely. The major advantage of
expected<T, E> over optional<T> is the ability to transport an error:
enum class errc {err1, err2, err3};
std::expected<int, errc> Foo()
{
if (/* error condition 1 */) return std::unexpected(errc::err1);
// ... checking other error conditions
return 42; // no error condition (42 is a good value)
// implicit conversion from `int` to `expected<int, errc>`
// avoid boilerplate code
}
int main()
{
auto q = Foo();
if (q)
{
// Do something with the return value here
}
}
You could also take a look at:
Functional exceptionless error-handling with optional and expected;
the standard proposal;
A possible implementation.
As a side note main() must return int.
It's my first year of using C++ and learning on the way. I'm currently reading up on Return Value Optimizations (I use C++11 btw). E.g. here https://en.wikipedia.org/wiki/Return_value_optimization, and immediately these beginner examples with primitive types spring to mind:
int& func1()
{
int i = 1;
return i;
}
//error, 'i' was declared with automatic storage (in practice on the stack(?))
//and is undefined by the time function returns
...and this one:
int func1()
{
int i = 1;
return i;
}
//perfectly fine, 'i' is copied... (to previous stack frame... right?)
Now, I get to this and try to understand it in the light of the other two:
Simpleclass func1()
{
return Simpleclass();
}
What actually happens here? I know most compilers will optimise this, what I am asking is not 'if' but:
how the optimisation works (the accepted response)
does it interfere with storage duration: stack/heap (Old: Is it basically random whether I've copied from stack or created on heap and moved (passed the reference)? Does it depend on created object size?)
is it not better to use, say, explicit std::move?
You won't see any effect of RVO when returning ints.
However, when returning large objects like this:
struct Huge { ... };
Huge makeHuge() {
Huge h { x, y, x };
h.doSomething();
return h;
}
The following code...
auto h = makeHuge();
... after RVO would be implemented something like this (pseudo code) ...
h_storage = allocate_from_stack(sizeof(Huge));
makeHuge(addressof(h_storage));
auto& h = *properly_aligned(h_storage);
... and makeHuge would compile to something like this...
void makeHuge(Huge* h_storage) // in fact this address can be
// inferred from the stack pointer
// (or just 'known' when inlining).
{
phuge = operator (h_storage) new Huge(x, y, z);
phuge->doSomething();
}
I'm currently in a C++ Course and im struggling with References. I know there are some similar topics, but i couldnt find an answer for this.
The thing is my Prof wants us to use References when returning objects, so return by value or using a pointer as return is no option.
So i guess i have to use a dynamic allocated object (returning a reference to a local object ends in a mess...right?)
1. Complex& method() {
2. Complex *object = new Complex();
3. return *object; }
Here is where im struggling, how do i catch the return right?
1. Complex one = object.method();
As far as i understand, with this i will get only a Copy and a Memory Leak
So how do i catch it with a pointer?
1. Complex *two = new Complex();
2. delete two;
3. *two = object.method();
this seems to work, but is there a way of it in just one line? Or should it be done different?
One idea is to store the returned object inside your object:
class Obj {
public:
Complex &method() { c.data = 10; return c; }
private:
Complex c;
};
This way there isn't any returning of local variable, or heap allocation.
returning a reference is efficient when you returning class member,
like:
class A{
Complex member;
public:
Complex& method(){
return member;
}
};
You also can return reference in manner to return some static or global object that can't be NULL, like:
Complex& method() {
static Complex c; // c cant be null
return c;
}
the advantage of using reference is that you can use the function call as an object, like: cin>>method().real>>method().img; and use the same object even if you call the method several times.
But your code doesn't feet to use reference, because each call creates a new instance.
if you are using dynamic allocation you should return a pointer:
Complex* method() {
return new Complex();
}
and you should remember to delete it.
my Prof wants us to use References when returning objects
When I read this, my first thought was that your professor meant:
void method(Complex& nonConstPassByReference)
{
nonConstPassByReference.data = 10;
}
or
int method(Complex& nonConstPassByReference)
{
nonConstPassByReference.data = 10;
return (0); // no error occurred
}
And when I use this technique, I now use
std::string method(Complex& nonConstPassByReference)
{
std::stringstream ss;
nonConstPassByReference.data = 10;
// more stuff
if (anErrorOccurred)
ss << errorDescriptionInfo << std::endl;
return (ss.str()); // no error occurred when return size is 0
}
This comes from the idea that, in general, all methods or functions can have two kinds of formal parameters. We call them pass-by-value, and pass-by-reference.
In general, all functions / methods can have both input and output formal parameters. And usually, input parameters are pass-by-value. Output parameters are non-const-pass-by-reference, inviting the method body to send its results back to the prebuilt instance of the calling code.
Occasionally, pass-by-reference variables are used for 'input-to-method' parameters (perhaps for performance - to avoid an expensive copy). In this case, the input-to-method-pass-by-reference parameters should be marked with 'const', to ask the compiler to generate an error if the code tries to modify that input.
Note that many C functions do NOT return a value which is part of the action ... return is instead an 'error occurred' indication, with the error description stashed in errno.