0

I have seen this asked before in several ways, and all the solutions are always the same: use a helper function or even use nested classes. For me, both of those solutions look clumpsy. So I wonder how come in the c++17/c++20 era there is not better solution to this problem:

EDIT: The question here is if there is any method to use impl<int> i(b);, because currently compiler fails due to the lack of second template argument.

template<class T1, class T2>
struct impl
{
    impl(const T2& _t2) : t2(_t2) {}

    T1 t1;
    const T2& t2;
};

int main()
{
    int a{};
    double b{};
    impl<int, double> i(b);//This works...
    impl<int> i(b);//... but this doesn't due to lack of 2nd template parameter!!!
}

I understand that partial spetialization can present problems in some cases, but it is not possible to use CTAD or any other method in this case??? If so, how?

Pablo
  • 557
  • 3
  • 16
  • 1
    Can you clarify your question? You said that you have seen solutions elsewhere but you're not satisfied with them? You need to state your question in a way that can be clearly answered. – Brian Bi Feb 09 '22 at 18:27
  • Yeah, the solutions I have seen are using nested classes or a helper function. The question is if is it posibble to use ```impl i(b);```, because currently the compiler fails when using it because the lack of second template parameter. – Pablo Feb 09 '22 at 18:31
  • 1
    Did you try deduction guides: https://en.cppreference.com/w/cpp/language/class_template_argument_deduction#User-defined_deduction_guides – Robert Andrzejuk Feb 09 '22 at 18:32
  • 1
    partial CTAD is not supported: https://stackoverflow.com/questions/57563594/partial-class-template-argument-deduction-in-c17/57563652#57563652 – NathanOliver Feb 09 '22 at 18:34
  • 2
    Deduction guides and CTAD will not work when explicitly specifying any of the template parameters. – super Feb 09 '22 at 18:34
  • Already answered by NathanOliver, CTAD was my first bet, but I have been not able to achieve any result with it. I have wondered whether was my fault or if it was not possible using it in this case – Pablo Feb 09 '22 at 18:35
  • 1
    You could of course make something like `impl i(b, dummy)` work, but I'm not sure this is preferrable... – fabian Feb 09 '22 at 18:39
  • Thanks fabian, but to me it doesn't seem better than a helper function. – Pablo Feb 09 '22 at 18:40

1 Answers1

2

I most often use a "type tag" to overcome this kind of problems. It also comes in handy for similar issues, like the lack of partial specialization of function templates.

#include <type_traits>

template<typename T> struct type_t{};
template<typename T> constexpr type_t<T> type;

template<class T1, class T2>
struct impl
{
    impl(const T2& _t2, type_t<T1> = {}) : t2(_t2) {}

    T1 t1;
    const T2& t2;
};

int main()
{
    int a{};
    double b{};
    impl<int, double> i(b);//This works...
    impl j(b, type<int>); // This works as well
    static_assert(std::is_same_v<decltype(j),impl<int, double>>);
}
Luppy
  • 66
  • 2
  • Thank you Luppy. Probably not the answer I expected, but you have provided a new point of view, that for this question, it's like a fresh breath. That is why I have chosen as the accepted answer. – Pablo Feb 09 '22 at 19:13