Вычет шаблона для аргумента шаблона по умолчанию

У меня есть класс, который выглядит примерно так:

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

До C++14, когда я хотел использовать его с аргументом шаблона по умолчанию, мне всегда приходилось указывать пустые угловые скобки:

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

Поскольку C++17 поддерживает вывод аргументов шаблона класса и явные руководства по выводу, мне интересно, есть ли способ заставить приведенный выше код работать без указания пустых угловых скобок:

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

Этот код работал в GCC 8.0, если я скомпилировал его с -std=gnu++17, Тем не менее, он все еще показал ошибку в Clang 6.0 и Visual Studio 15.7. Какой компилятор верен в этой ситуации?

Я также попытался указать руководство по выводу, как это:

C() -> C<char>;

Это тоже не помогло. Это правильный синтаксис или есть даже способ указать направляющие для конструктора по умолчанию?

1 ответ

Решение

Эта программа правильная:

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

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

Clang просто не полностью поддерживает вывод аргументов шаблона класса (обратите внимание, что он компилируется в транке).


При выводе аргумента шаблона класса будет выполнено разрешение перегрузки для набора кандидатов:

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

без инициализатора. Этот первый является жизнеспособным кандидатом (вывод T как char), второй нет, поэтому первый - тривиально лучший жизнеспособный кандидат. Таким образом, мы в конечном итоге c имеющий тип C<char>, Когда мы затем делаем разрешение перегрузки при построении по умолчанию, это работает, так что программа в порядке.

Другие вопросы по тегам