模板类编译错误

编程语言 2026-07-11

我一直在处理用 /std:c++17 编译的遗留MFC应用。它在升级为使用C++20之前可以正常编译。这个库我一直在开发的模板类依赖于一些ATL类。当我把它改成 c++20 时,编译时开始出现一条消息。

简化后的代码是:

#include <atldbcli.h>

template <class TAccessor = CAccessorBase>
class ARowset : public CRowset<TAccessor>
{
    HCHAPTER m_hChapter;
public:
    ARowset() : CRowset(), m_hChapter(NULL) {}

    HRESULT MoveLast()
    {
        ReleaseRows();

        return S_OK;
    }
};

int main()
{
    return 0;
}

错误信息是:

Source.cpp(16,3): error C3861: 'ReleaseRows': identifier not found
1>    Source.cpp(16,14):
1>    'ReleaseRows': function declaration must be available as none of the arguments depend on a template parameter
1>   Source.cpp(16,14):
1>    the template instantiation context (the oldest one first) is
1>        Source.cpp(8,7):
1>        while compiling class template 'ARowset'

我用那段代码新建了一个项目,即使使用 c++17 也无法编译。为什么它说未找到该标识符,应该如何修复?

解决方案

下面是最小可复现示例(MCVE):

template<typename T>
struct Base
{
    void foo(){}
};

template<typename T>
struct Derived: Base<T>
{
    void bar()
    {
        foo();
    }
};

int main()
{
    Derived<int>{}.bar();
}

在线编译器

这里的问题在于 Base::foo 是一个依赖于模板参数的名字,符合C++规范的实现必须在对 foo(); 的调用处发出错误。/std:c++17/std:c++20 的区别在于,后者意味着 /permissive-,这在某些方面会禁用遗留名称查找,以便获得更符合标准的行为。为了解决这个错误,你需要写成 Base<T>::foo();

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章