MSVC在constexpr-if中错误实例化不应被实例化的类模板
问题:MSVC在constexpr-if分支中意外实例化类模板,导致编译失败
我有一段代码可在GCC和Clang中正常编译,但在MSVC下编译失败。原因是MSVC会实例化constexpr-if语句中一个GCC和Clang都不会实例化的类模板。我已尽可能简化代码,示例如下:
#include <type_traits> class Foo { public: virtual void foo() = 0; protected: virtual ~Foo(){} }; template <typename E> struct Bar : public Foo { Bar(E const& e) : value(e) {} void foo() override final { bool x = std::is_pointer_v<E>; } E value; }; template <typename T> void some_function(){ auto inner_lambda = []() { if constexpr (!std::is_abstract_v<T>) { // MSVC为什么要实例化这个模板? Bar<T> u; } }; }; class Base { public: virtual void fun() = 0; protected: virtual ~Base(){} }; int main() { some_function<Base>(); return 0; }
编译器错误信息
<source>(22): error C2282: 'Bar<T>::~Bar' cannot override 'Foo::~Foo' with [ T=Base ] <source>(17): note: while compiling class template member function 'void Bar<T>::foo(void)' with [ T=Base ] <source>(31): note: see reference to class template instantiation 'Bar<T>' being compiled with [ T=Base ] <source>(45): note: see reference to function template instantiation 'void some_function<Base>(void)' being compiled Compiler returned: 2
有意思的是,我没法进一步简化这个示例,但以下几种操作能让MSVC编译通过:
- 将
foo改为Bar的非虚成员函数 - 移除
foo中对std::is_pointer_v<E>的调用 - 不把
if constexpr嵌套在some_function的内部lambdainner_lambda中 - 将
Base的虚析构函数设为public
这些操作看起来都和核心问题无关,所以我怀疑这是MSVC的编译器bug,请问这个判断正确吗?
内容的提问来源于stack exchange,提问作者joergbrech
相关产品推荐
相关产品推荐

