You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的内部lambda inner_lambda中
  • 将Base的虚析构函数设为public

这些操作看起来都和核心问题无关,所以我怀疑这是MSVC的编译器bug,请问这个判断正确吗?

内容的提问来源于stack exchange,提问作者joergbrech

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 11:25:38