模板 class 使用 C++17 编译,但如果无法编译未使用的函数,则不使用 C++20
Template class compiles with C++17 but not with C++20 if unused function can't be compiled
在 VS2019(版本 16.11.15)中选择 C++ 17 作为语言,以下编译没有错误。但它因 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();
}
Anon
class 当然是未定义的,但是 ::do_something 函数未被使用,因此不需要实例化。这在 C++17 中是可以的,但在 C++20 中显然不行。
这是语言规则的变化吗?如果是这样,是否可以在不实际定义 Anon
的情况下修复它?
Is this a change in language rules?
不,这是因为 允许(但不是必需的!)C++ 编译器在解析模板时诊断错误
当模板的所有实例化都会产生该错误时。
这意味着对于您给出的示例,在解析定义时编译器可能会或可能不会发出错误。也就是说,编译器在解析模板时可能会产生错误,或者可能会等到第一个模板实例化。请参阅 Demo,其中 msvc 不会发出错误,但 gcc 和 clang 会发出错误。
也许一个更简单的例子会更清楚:
void func()
{
}
template<typename T> void bar()
{
func(3); //compilers are allowed(but not required) to issue error at the time of pasrsing this
}
在上面的示例中,func
是一个 非依赖名称 并且在我们使用 func(3)
调用 func
的地方, only visible func
是接受 0
参数的那个,而不是一个。正如我之前所说,有些编译器可能会发出错误(在解析时),即使我们没有实例化 bar
但有些编译器可能不会。这是因为允许但不要求他们这样做。请参阅 demo,其中 msvc 不会在此处发出错误,但 gcc 和 clang 会发出错误。
同样的逻辑也适用于您的示例。意思是 Anon
是一个不完整的类型,而你有 anon.do_something()
,一些编译器可能会选择产生错误,即使你没有实例化 a_template
而其他一些编译器可能不会。
在 VS2019(版本 16.11.15)中选择 C++ 17 作为语言,以下编译没有错误。但它因 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();
}
Anon
class 当然是未定义的,但是 ::do_something 函数未被使用,因此不需要实例化。这在 C++17 中是可以的,但在 C++20 中显然不行。
这是语言规则的变化吗?如果是这样,是否可以在不实际定义 Anon
的情况下修复它?
Is this a change in language rules?
不,这是因为 允许(但不是必需的!)C++ 编译器在解析模板时诊断错误 当模板的所有实例化都会产生该错误时。
这意味着对于您给出的示例,在解析定义时编译器可能会或可能不会发出错误。也就是说,编译器在解析模板时可能会产生错误,或者可能会等到第一个模板实例化。请参阅 Demo,其中 msvc 不会发出错误,但 gcc 和 clang 会发出错误。
也许一个更简单的例子会更清楚:
void func()
{
}
template<typename T> void bar()
{
func(3); //compilers are allowed(but not required) to issue error at the time of pasrsing this
}
在上面的示例中,func
是一个 非依赖名称 并且在我们使用 func(3)
调用 func
的地方, only visible func
是接受 0
参数的那个,而不是一个。正如我之前所说,有些编译器可能会发出错误(在解析时),即使我们没有实例化 bar
但有些编译器可能不会。这是因为允许但不要求他们这样做。请参阅 demo,其中 msvc 不会在此处发出错误,但 gcc 和 clang 会发出错误。
同样的逻辑也适用于您的示例。意思是 Anon
是一个不完整的类型,而你有 anon.do_something()
,一些编译器可能会选择产生错误,即使你没有实例化 a_template
而其他一些编译器可能不会。