Reputation: 149
I have a class structured like this, where FixedStr
is implicitly constructible from a string-literal:
template<FixedStr K, class... T>
struct ParserCtx {
Parser<T...> parser;
ParserCtx(std::string_view description, Parser<T...>&& parser)
: parser(std::move(parser))
{}
};
I intended to use it in the following way, with T
being deduced from invocations of the constructor.
ParserCtx<"name">{"desc", Parser{1, 2.0, 3.0f}};
However, as you know, this doesn't work, because CTAD is all-or-nothing. From cppreference:
Class template argument deduction is only performed if no template argument list is present. If a template argument list is specified, deduction does not take place.
I was surprised to find that this isn't true of function-templates, so the usage described above can be 'emulated' using function-templates.
template<FixedStr K, class... T>
auto ParserCtx(std::string_view desc, Parser<T...>&& parser) -> impl::ParserCtx<K, T...> {
return {desc, std::move(parser)};
}
ParserCtx<"name">("desc", Parser{1, 2.0, 3.0f});
However, it occurred to me that I'd actually seen this many times before when using 'helper' functions like std::to_array
.
std::array<int>{1, 2, 3}; // N is not deduced
std::to_array<int>({1, 2, 3}); // N is deduced
Why does argument deduction behave differently in these different contexts?
Upvotes: 1
Views: 34