TGViewer
C++ - Reddit C++ - Reddit @r_cpp · 230 subscribers
Post #25201 23
FYI: Class Template Argument Deduction (CTAD) does not compose well with Designated Initializers

I've been playing around with Designated Initializers lately to see if I can use them for robust NAMED function parameters. It seemed promising at first, but I've hit a wall when it comes to type deduction.

Instead of explaining all the steps, I'll just share where things ended up. So to define an API that uses designated initializers and CTAD, you end up with something like this:

struct NotProvided {};
template <
typename Size = NotProvided,
typename Capacity = NotProvided,
typename Factory = NotProvided
\>
struct Params {
Size size = {};
Capacity capacity = {};
Factory factory = {};
};
template <typename T>
struct Vector {
Vector(auto params) {
// ...pick apart the Params object...
}
};

You can and should make use of concepts to give more type information to the caller. Unconstrained templates are not as helpful when debugging, but I'm using them here to clarify the problem.

So given a callsite like this:

int64_t counter = 0;
auto v1 = Vector<int64_t>(Params{
.size = 0,
.capacity = 10,
.factory = [&\](int64_t* addr) {
::new (addr) int64_t(counter);
\++counter;
},
});

This should work fine and was what got me excited about the prospects of things. But once I started actually writing types like Vector and their tests, I kept getting surprising template error messages. One category was the deduction of reference types instead of underlying value types. That alone is infuriating but can be resolved with extra steps.

Instead, the deeper issue has to do with the interaction between CTAD and designated initializers. Consider this callsite:

auto v2 = Vector<int64_t>(Prams{
.size = 20,
.factory = DefaultFactoryFor<int64_t>,
});

This won't work. And the reason why is very upsetting.

When performing Class Template Argument Deduction, it first does an unevaluated invocation a synthesized overload set. That overload set, in this case, looks roughly like this:

Params();
Params(auto size);
Params(auto size, auto capacity);
Params(auto size, auto capacity, auto factory);

Then, when performing this invocation, it just uses the values of the arguments. It does not consider the field names.

So that means...

Params{.size = 10, .factory = DefaultFactoryFor<int64_t>}

... becomes ...

Params{10, DefaultFactory<int64_t>}

... which causes CTAD to select ...

Params(auto size, auto capacity);

Since the assumptions made about `auto capacity` are incompatible with the assumptions made about `.factory` arguments, this fails to compile!

I really wish that CTAD understood the field names when invoked via designated initializers.

I expected the default type values (`NotProvided`) and default member initializers (` = {}`) to work here. I thought it would unambiguously invoke the CTAD `Params(auto, auto, auto)` overload because all the arguments I did not spell (`.capacity`) would be "injected" into the callsite prior to type deduction. But that is not what happens.

If anyone knows a solution to this, I would be very happy.

https://redd.it/1te2yj1
@r_cpp
Reddit From the cpp community on Reddit Explore this post and more from the cpp community
More from @r_cpp
  1. Oct 3, 2026C++ future at Adobe So if anyone was still curious what happened to Hylo, or where Adobe s…
  2. Oct 3, 2026C++ Jobs - Q4 2026 Rules For Individuals --------------------- * **Don't** create top-leve…
  3. Sep 29, 2026Boost.Graph 1.95 will be C++17 Dear Boost.Graph community, In two release cycles (Boost re…
  4. Sep 26, 2026Token Sequence Injection & Modern Macros: The Most Game-Changing Compile-Time Feature in C…
  5. Sep 25, 2026myStringStream.str("") Considered Harmful Under C++20 I was recently looking at some (rath…
  6. Sep 20, 2026A clever branch free optimization I'm the developer of memlz which is an extremely fast co…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →