Trouble with seeing where variable is initialized?

Apr 20, 2024 at 6:25pm
Hello,

This question is in regards to the initialization of the variable value_type value;

I can see that the struct foo is typed as the wrapper<int> but cannot find how wrapped_value.value becomes 42? I don't see an initialization list or a constructor in the foo struct, just f{ 42 }?

here's the complete code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>

template <typename T>
struct wrapper
{
   using value_type = T;
   value_type value;
};
template <typename T>
struct foo
{
   T wrapped_value;
   typename T::value_type get_wrapped_value()
   {
	   return wrapped_value.value;
   }
};
int main()
{
   foo<wrapper<int>> f{ 42 };
   std::cout << f.get_wrapped_value() << '\n';
}
Last edited on Apr 20, 2024 at 6:26pm
Apr 20, 2024 at 6:48pm

 
foo<wrapper<int>> f{ 42 }; <-- Aggregate intitialization

Basically, foo<wrapper<int>> and wrapper are "aggregates" because all data members are public and there are no user-declared constructors, that's why you can initialize like that.

https://en.cppreference.com/w/cpp/language/aggregate_initialization
Last edited on Apr 20, 2024 at 6:51pm
Apr 20, 2024 at 6:59pm
Basically, foo<wrapper<int>> and wrapper are "aggregates" because all data members are public and there are no user-declared constructors, that's why you can initialize like that.


this is only for structs, not classes? Thanks for your help btw.
Apr 20, 2024 at 7:00pm
Note that you can also write it like this:

 
foo<wrapper<int>> f{ { 42 } };

which might make more sense to you because you can think of the outer pair of braces as belonging to the foo<wrapper<int>> object and the inner pair of braces belonging to the wrapper<int> object.

The {} initialization syntax has this rule that you can often remove extra braces (this goes back to C) which is why you can write it with only one pair of braces.


Compare this to how you can initialize a multidimensional array like this:

1
2
3
4
5
int arr[2][3] =
{
	{1, 2, 3},
	{4, 5, 6}
};

But you can also initialize it like this:

1
2
3
4
5
int arr[2][3] =
{
	1, 2, 3,
	4, 5, 6
};

Both of these mean the exact same thing.
Last edited on Apr 20, 2024 at 7:04pm
Apr 20, 2024 at 7:03pm
lostwithcpp wrote:
this is only for structs, not classes?

Technically there is no difference between "class" and "struct" in C++ except for the default accessibility (struct defaults to public while class defaults to private). Your example would work exactly the same if you used the class keyword and explicitly made the members public.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>

template <typename T>
class wrapper
{
public:
   using value_type = T;
   value_type value;
};
template <typename T>
class foo
{
public:
   T wrapped_value;
   typename T::value_type get_wrapped_value()
   {
	   return wrapped_value.value;
   }
};
int main()
{
   foo<wrapper<int>> f{ 42 }; // still works
   std::cout << f.get_wrapped_value() << '\n';
}
Last edited on Apr 20, 2024 at 7:08pm
Topic archived. No new replies allowed.