Это правильный способ выполнения "Выражение SFINAE" в C ++ 03? - PullRequest
0 голосов
/ 26 сентября 2018

В C ++ 11 легко определить, является ли выражение допустимым.Например, представьте себе, проверяется, является ли что-либо пригодным для обработки:

template <typename T>
auto print_if_possible(std::ostream& os, const T& x) 
    -> decltype(os << x, void());

print_if_possible будет участвовать только в разрешении перегрузки , если os << x является правильно сформированным выражением.

живой пример на godbolt.org


Мне нужно сделать то же самое в C ++ 03, и я понял, что sizeof можетпомощь (так как мне нужен неоцененный контекст для выражения).Вот что я придумал:

template <int> struct sfinaer { };

template <typename T>
void print_if_possible(std::ostream& os, const T& x, 
    sfinaer<sizeof(os << x)>* = NULL);

живой пример на godbolt.org


Кажется, что оба последнихверсии g ++ и clang ++ принимают версию sizeof с -std=c++03 -Wall -Wextra.

  • Гарантированно ли работает код, предназначенный для C ++ 03?

  • Правильно ли сделать вывод, что любое использование C ++11 Выражение SFINAE можно перенести в C ++ 03 с помощью sfinaer и sizeof?

1 Ответ

0 голосов
/ 27 сентября 2018

Выражение SFINAE немного серое.C ++ 03 в основном ничего не сказал по этому вопросу.Он ни явно не запретил, ни явно не допустил.Современные реализации не позволяли такие конструкции, потому что это вызывало существенную сложность реализации, и неясно, должно ли это быть разрешено, и CWG в какой-то момент *1002* склонялась к его запрету (см. Примечание за апрель 2003 года), прежде чем в конечном итоге обратный курс , частично в свете decltype и constexpr, которые были добавлены в C ++ 11 (см. Введение в N2634).

Это также все произошло задолго до начала CWGЯвно отмечать состояние аварийного восстановления проблем, решения которых должны применяться задним числом.

Я думаю, что лучший совет здесь - просто «спросить своего поставщика компилятора».Компилятор, который поддерживает выражение SFINAE в своем режиме C ++ 11, вряд ли откажется от этой поддержки в режиме C ++ 03 (поставщик может рассматривать CWG 339 как отчет о дефектах и ​​применять его задним числом или рассматривать как расширение).OTOH, компилятор, который никогда не поддерживал C ++ 11, вряд ли вложит значительные затраты, необходимые для работы выражения SFINAE (действительно, он работал не в каком-то крупном компиляторе кашель до относительно недавнего времени).Я также подозреваю, что место, где все еще есть язык 15-летней давности, вряд ли будет использовать современные наборы инструментов, необходимые для такой поддержки.

...