简体   繁体   English

如果无法编译未使用的函数,则模板类可以使用 C++17 编译,但不能使用 C++20 编译

[英]Template class compiles with C++17 but not with C++20 if unused function can't be compiled

The following compiles without error in VS2019 (version 16.11.15) with C++ 17 selected as the language.以下在选择 C++ 17 作为语言的 VS2019(版本 16.11.15)中编译没有错误。 But it fails with C++ 20 with error "error C2027: use of undefined type 'Anon'"但它在 C++ 20 中失败,出现错误“错误 C2027:使用未定义类型‘Anon’”

template <typename T> class a_template
{
public:
    void do_something(class Anon& anon) const;
};

template <typename T> void a_template<T>::do_something(class Anon& anon) const
{
    anon.do_something();
}

The Anon class is of course undefined but the ::do_something function is unused so does not need to be instantiated. Anon类当然是未定义的,但 ::do_something 函数未使用,因此不需要实例化。 This is OK in C++17 but apparently not in C++20.这在 C++17 中是可以的,但在 C++20 中显然不行。

Is this a change in language rules?这是语言规则的变化吗? If so, can it be fixed without actually defining Anon ?如果是这样,是否可以在不实际定义Anon的情况下对其进行修复?

Is this a change in language rules?这是语言规则的变化吗?

No, this is due to the fact that a C++ compiler is permitted (but not required!) to diagnose errors at the time the template is parsed when all of the instantiations of the template would produce that error .不,这是因为允许(但不是必需的!)C++ 编译器在模板被解析时诊断错误,而模板的所有实例都会产生该错误

This means that for your given example, at the time of parsing the definition compilers may or may not issue an error.这意味着对于您给定的示例,在解析定义时编译器可能会或可能不会发出错误。 That is, the compiler can produce an error when parsing the template or may wait until the first template instantiation.也就是说,编译器在解析模板时可能会产生错误,或者可能会等到第一个模板实例化。 Refer to demo where msvc doesn't issue an error but gcc and clang does.请参阅演示,其中 msvc 不会发出错误,但 gcc 和 clang 会发出错误。

Perhaps a simpler example would make it more clear :也许一个更简单的例子会更清楚:

void func()
{

}

template<typename T> void bar() 
{
     func(3); //compilers are allowed(but not required) to issue error at the time of pasrsing this
}

In the above example, func is a nondependent name and at the point where we have called func using func(3) , the only visible func is the one that accepts 0 arguments and not one.在上面的例子中, func是一个不依赖的名字,在我们使用func(3)调用func的地方,唯一可见的func是接受0个参数而不是 1 个参数的那个。 And as i said earlier, some compiler may issue an error(at the time of parsing) even though we've not instantiated bar but some compilers may not.正如我之前所说,即使我们没有实例化bar但某些编译器可能不会,某些编译器可能会发出错误(在解析时)。 This is because they are allowed to but not required to do so.这是因为他们被允许但不是必须这样做。 See demo where msvc doesn't issue an error here but gcc and clang does.请参阅演示,其中 msvc 不会在此处发出错误,但 gcc 和 clang 会。


The same logic applies to your example as well.同样的逻辑也适用于您的示例。 Meaning as Anon is an incomplete type and you have anon.do_something() , some compiler might choose to produce an error even though you have not instantiated a_template and some other compiler might not.意思是Anon是一个不完整的类型并且您有anon.do_something() ,即使您没有实例化a_template并且某些其他编译器可能没有,某些编译器可能会选择产生错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM