Do we still need class template argument deduction guide in C++20?

Hi,

Here the deduction guide is not needed on most compilers:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>

template<typename T, typename U>
class Test {
    T t;
    U u;
public:
     Test(T t, U u) : t(t), u(u) {}
     void print() { std::cout << t << ' ' << u << '\n'; } 
};
    
//template<typename T, typename U>
//Test(T,U) -> Test<T,U>;

int main() {
   Test T1 {3, 4.4};
   T1.print(); 
}


Is the reason because the class is so simple or we don't need CTAD guides anymore in C++20?
Last edited on
https://en.cppreference.com/w/cpp/language/class_template_argument_deduction

frek wrote:
Here the deduction guide is not needed on most compilers:


It is using CTAD, maybe you are confused with User-defined deduction guides? //Test(T,U) -> Test<T,U>;

Can you explain why cppreference has all that documentation if CTAD wasn't required anymore since C++17?

Yeah, it's a good question and probably we still need class template argument deduction guides even if the compiler uses C++20.
But I thought since C++20 makes uses of concepts, there shouldn't be that much need for those guides anymore.
If we still need such guides even in modern CPP, could you give me a link to a simpler tut than cppreference to study it to some extend to be able to use it in C++20 when/where needed, please.
You missed that there are implicitly-generated deduction guides that work for the majority of cases.

Anyway the point of CTAD is to figure out the type of a class from the type of its constructor arguments.

Here's an example of a class template that benefits from a user-defined deduction guide:
typename <typename T, int N> struct my_array { T data[N]; };
We'd like the compiler to deduce that the type of my_array{ 1, 2, 3 } is my_array<int, 3>, but it can't do that without help.

We can define a deduction guide to help the compiler.
1
2
template <typename T, typename... Ts> 
  my_array(T, Ts...) -> my_array<T, 1 + sizeof... (Ts)>;
Note the deduction guide looks like a declaration of a constructor template with a trailing return type.

The compiler makes one fake function template for every deduction guide.
For example the compiler invents this function from the deduction guide above:
1
2
template <typename T, typename... Ts> 
  auto my_array(T, Ts...) -> my_array<T, 1 + sizeof... (Ts)>;
Then, when the compiler encounters
my_array{ 1, 2, 3 }
It "calls" the fake function template (or templates, if there are more deduction guides) with the constructor arguments:
my_array(1, 2, 3) // returns my_array<int, 3>
And uses the type of that expression as the type of the class.

Please note this is simplified.
Last edited on
If my_array is a class/struct, why doesn't it have such a specifier before its name!? What is the type of data member data!?
My mistake, it should have been
typename <typename T, int N> struct my_array { T[N] data; };
What is this: T[N] data; please?
A typo? Perhaps T data[N];
Yes, thanks. Here's an example that actually compiles:
1
2
3
4
5
6
7
8
9
10
11
12
template <typename T, int N> struct my_array { T data[N]; };
template <typename T, typename... Ts> 
  my_array(T, Ts...) -> my_array<T, 1 + sizeof... (Ts)>;
  
#include <type_traits>

int main()
{
  my_array a1 = { 1, 2, 3 }; 
  
  static_assert(std::is_same<decltype(a1), my_array<int, 3>>::value); 
}
Registered users can post here. Sign in or register to post.