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

延迟模板实例化中的编译器分歧:代码合规性与正确性判定

基类模板成员函数检测的编译器行为与标准合规性问题

我希望在基类未实现指定成员函数时触发static_assert,编写了如下C++代码:

#include<type_traits>
  
template<typename T>
struct AlwaysFalse : public std::false_type {};

struct B
{
  template<typename S>
  void foo(){}
};

template <typename T,typename S>
struct A : T
{
  auto foo(){
    if constexpr (requires{ T::template foo<S>(); })
      return 1;
    else
      static_assert(AlwaysFalse<A>::value, "foo is not implemented.");
  }
};

int main()
{
  A<B, double> a;
  a.foo();
}

这段代码在GCC 12.2中可以正常编译,但在Clang 16及开发版本中编译失败;如果将基类的foo改为非模板函数,Clang也能正常编译。

我有两个疑问:

  • 哪个编译器的行为是正确的?我认为是GCC,因为基类的成员函数确实存在,不应该触发static_assert。
  • 上述代码是否符合C++标准?

另外我找到了一个兼容两种编译器的解决方案,修改requires表达式,在其中创建基类对象:

if constexpr (requires(T t){ t.template foo<S>(); })

相关测试场景说明:

  • 模板版本:原代码场景,基类foo为模板函数
  • 非模板版本:基类foo改为非模板函数的场景
  • 兼容方案:修改requires表达式后的代码场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 17:23:11