The question is simple. Is it possible to construct such a type T, for which the following two variables declarations will produce different results?
T t1 = {};
T t2{};
I've been digging through the cppreference and the standard for more than an hour now, and I understood the following:
T t2{};
is a value initialization. No surprises here.T t1 = {}
is a list initialization with an empty braced-init-list. But the last one is tricky since the "effects of list initialization" is an impressive... list. Which for classes, fundamental types and aggregates seems to boil down to value initialization. But I am not sure I haven't missed anything.
Maybe you can provide a context, in which the two declarations will have different effects?
UPD: Excellent answers about explicit
constructors! Next level: is it possible that both statements compile, but have different effects on compile/run time?
In JavaScript, all function arguments are always passed by value. It means that JavaScript copies the values of the variables into the function arguments. Any changes that you make to the arguments inside the function do not reflect the passing variables outside of the function.
The original variable won't change even if we change the argument variables that we passed in. Primitive data types like string, number, boolean, undefined and the null object is passed in by value in TypeScript.
Yes, Javascript always passes by value, but in an array or object, the value is a reference to it, so you can 'change' the contents.
The difference between pass-by-reference and pass-by-value is, pass-by-value creates a new space in memory and makes a copy of a value, whereas pass-by-reference does not. Instead of making a copy, pass-by-reference does exactly what it sounds like; a value stored in memory gets referenced.
If you consider a case in which one statement will compile, but the other will not compile as "different effects," then yes, here's a context:
#include <iostream>
class T {
public:
int data{ 0 };
explicit T() {
data = 0;
std::cout << "Default constructor" << std::endl;
}
};
int main()
{
T t1 = {};
T t2{};
return 0;
}
The line declaring/initializing t1
gives the following, with clang-cl
:
error : chosen constructor is explicit in copy-initialization
The MSVC
compiler also complains:
error C2512: 'T': no appropriate default constructor available
message : Constructor for class 'T' is declared 'explicit'
The difference is in explicit
. I've managed to make msvc difference, but it looks like a compiler bug:
#include <iostream>
#include <initializer_list>
struct T
{
template<class... A>
T(A...) {std::cout << "1\n";}
explicit T() { std::cout << "2\n"; }
};
int main()
{
T t1 = {}; // 1
T t2{}; // 2
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With