[英]C++: Why does the compiler instantiate a template when it is not used
Let's consider this code: 让我们考虑以下代码:
template <bool c>
class A {
public:
A() = default;
// I want to enable f(int) only if c == true
template<typename Temp = typename enable_if<c>::type>
void f(int val) {
cout << val << endl;
};
};
int main() {
A<false> a;
A<true> b;
b.f(543);
}
When I try to compile this I get the following error: 当我尝试对此进行编译时,出现以下错误:
error: no type named 'type' in 'struct std::enable_if<false, void>'
But I don't use the template method f(int)
when the argument <bool c>
is false
then it shouldn't exist. 但是当参数
<bool c>
为false
时,我不使用模板方法f(int)
,那么它不应该存在。
The compiler does not "instantiate" your template, as you seem to incorrectly believe. 您似乎不正确地相信编译器不会“实例化”您的模板。 The compiler is simply trying to parse and analyze your template declaration, which is a part of your class definition.
编译器只是在尝试解析和分析模板声明,这是类定义的一部分。 If the class is instantiated, then all member declarations have to be valid.
如果实例化该类,则所有成员声明都必须有效。 Your member template declaration is not valid.
您的成员模板声明无效。 Hence the error.
因此,错误。
If some template is "not used", it means that it does not get specialized and instantiated. 如果某些模板“未使用”,则意味着它不会被专门化和实例化。 But the declaration of that template still has to be valid.
但是该模板的声明仍然必须有效。 And the validity of those parts of that declaration that do not depend on template parameters is checked immediately.
并立即检查不依赖模板参数的那些声明部分的有效性。 In other words, what you wrote in your code is no different from
换句话说,您在代码中编写的内容与
template <typename T = jksgdcaufgdug> void foo() {}
int main() {}
or, closer to your situation 或者,更贴近您的情况
template <typename T = std::enable_if<false>::type> void foo() {}
int main() {}
Even though these programs do not "use" (do not instantiate) function template foo
, it still does not mean that the declaration of foo
can contain random garbage like jksgdcaufgdug
or explicitly refer to non-existent entities like std::enable_if<false>::type
. 即使这些程序不“使用”(不实例化)功能模板
foo
,也并不意味着foo
的声明可以包含jksgdcaufgdug
类的随机垃圾,也jksgdcaufgdug
明确引用诸如std::enable_if<false>::type
类的不存在的实体std::enable_if<false>::type
。 The above examples will not compile for that reason. 由于上述原因,以上示例将无法编译。
You can use "random garbage" in dependent contexts, like 您可以在相关上下文中使用“随机垃圾”,例如
template <typename T> void foo(typename T::kjhdfjskhf x)
{
typename T::jksgdcaufgdug i;
}
and you can use std::enable_if
in dependent contexts like 并且您可以在类似的依赖上下文中使用
std::enable_if
template <typename T,
typename U = typename enable_if<is_void<T>::value>::type>
void bar()
{
}
and it will not produce "early" errors, but in your case enable_if<c>
does not depend on Temp
, so it is not in dependent context. 并且不会产生“早期”错误,但是在您的情况下,
enable_if<c>
不依赖于Temp
,因此它不在依赖上下文中。 Which means that the correctness of typename enable_if<c>::type
is checked immediately when you instantiate A<false>
. 这意味着实例化
A<false>
时会立即检查typename enable_if<c>::type
名称typename enable_if<c>::type
的正确性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.