170 похожих чатов

Template <typename U, bool T = true> class C{ public: template<typename = std::enable_if_t<!T>> explicit

C(int x, int y){}
template<typename = std::enable_if_t<T>>
explicit C(int x) {}
};

int main(){

C<int> a(2);

return 0;
}

почему такое компилится msvc и не компилится gcc и клангом. Где баг где фича?

10 ответов

15 просмотров
Pepe 🐸- Автор вопроса

По идее не должно компилиться, потому что substitution тут нет, но msvc компилит

Упрощу пример, убрав всё лишнее: template <bool T> class C { public: template<typename = std::enable_if_t<!T>> void foo(){} }; // ... C<true> a{}; По сути, когда мы инстанцируем C, мы получаем эквивалент следующего псевдокода: template <> class C<true> { public: template<typename = std::enable_if_t<!true>> void foo(){} }; Так что да, enable_if_t всегда содержит ложное условие для текущей специализации C, что равнозначно написанию std::enable_if_t<false> в любом нешаблонном контексте — это всегда ошибка компиляции и SFINAE не спасает потому что тут нет SFINAE-контекста. GCC и Clang, кажется правы Могу лишь предположить, что MSVC откладывает момент инстанцирования дефолтного параметра функции до инстанцирования самого шаблона функции

Ofee Oficsu
Упрощу пример, убрав всё лишнее: template <bool T...

Интересно, что констрейнты справляются: template <bool B> struct C { void foo() requires (!B) {} }; int main() { C<true> a; } При этом вызов a.foo() будет ошибкой. Я попытался придумать как воспроизвести исключение метода из класса без requires и такое чувство, что никак. Приходят в голову методы-уродцы исключить через CRTP (наследуясь от базового класса в котором есть или нет и т.п.), но если поставить условие обойтись без наследования, то интересно есть ли метод воспроизвести шаблонной магией то, что легко делают констрейнты?

Konstantin Vladimirov
Интересно, что констрейнты справляются: template ...

template <bool B> struct X { template <bool B_ = B, [sfinae on B_]> void foo(); }; Должно решить проблему

Konstantin Vladimirov
Интересно, что констрейнты справляются: template ...

>> Интересно, что констрейнты справляются Да, если не ошибаюсь, это намеренно заложенное в них поведение, чтобы упростить включение/выключение функций в зависимости от параметров класса (в том числе деструктора)

Alexander Karaev
template <bool B> struct X { template <bool B_ =...

Да, логично, спасибо. Я чего-то не подумал. Просто распространяем SFINAE вниз. И так же чинится оригинальный кейс от @scaredpepe https://godbolt.org/z/3Yro8GnYd

Ofee Oficsu
>> Интересно, что констрейнты справляются Да, есл...

без этого зачем вообще они нужны были бы?)

Kelbon
без этого зачем вообще они нужны были бы?)

Довольно странное заявление при том, что они: 1) значительно упрощают код; 2) зависимы между собой и позволяют "перегрузки"; 3) лучше понятны компилятору, что потенциально упрощает и ускоряет диагностику ошибок компилятором

Konstantin Vladimirov
Да, логично, спасибо. Я чего-то не подумал. Просто...

Я бы добавил ещё один интересный хак: template <bool B> struct X { template <typename..., bool B_ = B, [sfinae on B_]> void foo(); }; Это не позволит случайно переопределить дефолтный параметр извне. По желанию добавить ограничение ещё и на то, чтобы пак был пуст

Pepe 🐸- Автор вопроса
Ofee Oficsu
Упрощу пример, убрав всё лишнее: template <bool T...

Да, только получается MSVC вообще не инстанцирует его

Похожие вопросы

Обсуждают сегодня

Anyone here suffers from unexplained aural migraines, who would be up for talking for a bit? Doesn't *have* to be aural, but I am not asking about headaches, I mean actual mi...
Martin Rys
55
подскажите пожалуйста, как мне освободить результат записанный в переменную result? в чем проблема подскажите если МОЖЕТЕ?
Михаил Helper
28
Слушайте, ещё такая интересная задачка. Сделан аудит действий пользователей через триггеры в базе, соответственно каждый пользователь имеет свой логин и пароль в базе. Это пре...
Сергей Бычков
12
есть тут кто-то , кто только начал изучать си? если проходите курс на степике или как-то сами изучаете, пишите, может, скооперируемся?..
Eule
25
вопрос по москвину - не понимаю вот такого вопроса похоже Сколько разных всегда завершающихся функций с типом a -> a -> b -> a -> a можно реализовать? Две функции одинаково...
Fedor
11
Скажите, тут нет проблемы? IMyInterface1 = interface function GetInterface2: IInterface2; ... function TMyInterface.GetInterface2: IInterface2; begin Result := TI...
Ruslan aka DUDE
18
Утра доброго. Просветите пожалуйста. Хочу сделать rest сервер на делфи. Посмотрел 3 фреймворка: dmvc, Mars, mormot. Ни в одном из них не упоминается ассинхронная обработка вхо...
Сергей Бычков
10
Как попросить stack install делать executable без .exe на винде?
Danila Danko
9
я не магистр хаскеля, но разве не может лейзи тип конвертнуться в не-лейзи запросив вычисление содержимого прям при инициализации?
deadgnom32 λ madao
100
возможно для форматирования TimeStampZ нужен другой механизм, не?
Роман Лях (rgreat)
13
Карта сайта