Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template deduction for default template argument

Tags:

c++

c++17

I have a class that looks similar to this:

template <class T = char>
struct C {
    T value;
};

Up to C++14, when I wanted to use it with the default template argument I always had to specify empty angle brackets:

void f() {
    C<> c;
    c.value = 'x';
}

Since C++17 supports class template argument deduction and explicit deduction guides, I wonder if there is a way now to make the above code work without specifying the empty angle brackets:

void f() {
    C c;
    c.value = 'x';
}

This code worked in GCC 8.0 if I compile it with -std=gnu++17. However, it still showed an error in Clang 6.0 and Visual Studio 15.7. Which compiler is correct in this situation?

I also tried specifying a deduction guide like this:

C() -> C<char>;

This also didn't help. Is that the correct syntax or is there even a way to specify deduction guides for a default constructor?

like image 302
fschoenm Avatar asked May 11 '18 13:05

fschoenm


1 Answers

This program is correct:

template <class T = char>
struct C {
    T value;
};

int main() {
    C c;
    c.value = 'x';
}

clang just doesn't fully support class template argument deduction yet (note that it does compile on trunk).


Class template argument deduction will try to perform overload resolution on the candidate set:

template <class T=char> auto __f()     -> C<T>
template <class T=char> auto __f(C<T>) -> C<T>

with no initializer. That first one is a viable candidate (deducing T as char), the second one is not, so the first one is trivially the best viable candidate. So we end up with c having type C<char>. When we then do overload resolution on default construction, that works, so the program is fine.

like image 185
Barry Avatar answered Oct 24 '22 12:10

Barry