Я пытаюсь понять, должен ли приведенный ниже фрагмент компилироваться в соответствии со стандартом или нет. Когда я пытаюсь скомпилировать его с последней версией трех основных компиляторов, происходит следующее:
- ✓ Clang (версия 7.0.0, с
-std=c++17
): прекрасно компилируется; - ✓ GCC (версия 8.2, с
-std=c++17
): также хорошо компилируется; - ❌ MSVC (версия 19.16, с флагом
/std:c++17
): ошибка компилятора (см. Ниже).
Ошибка возникает из-за того, что компилятор MSVC пытается создать экземпляр std::optional<void>
несмотря на то, что код отбрасывается. GCC и Clang, похоже, этого не делают.
Стандарт четко определяет, что должно произойти в этом случае?
#include <optional>
#include <type_traits>
template<typename T, typename... Args>
struct Bar
{
void foo(Args... args)
{
if constexpr(!std::is_same_v<T, void>) // false
{
// MSVC compiler error occurs because of the line below; no error occurs when compiling with GCC and Clang
std::optional<T> val;
}
}
};
int main(int argc, char** argv)
{
Bar<void, int> inst;
inst.foo(1);
return 0;
}
Ошибка MSVC:
C:/msvc/v19_16/include\optional(87): error C2182: '_Value': illegal use of type 'void' C:/msvc/v19_16/include\optional(128): note: see reference to class template instantiation 'std::_Optional_destruct_base<_Ty,false>' being compiled with [ _Ty=void ]