简体   繁体   English

C ++:为什么编译器在不使用模板时将其实例化

[英]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.

相关问题 为什么我的(C++)编译器在使用 std::endl 时想要实例化我的参数包 class? - Why does my (C++) compiler want to instantiate my parameter pack class when using std::endl? 当用作模板参数时,C ++编译器不区分类型和函数名称 - C++ compiler does not distinguish type and function name when used as template parameter C ++:编译器仅按需实例化模板函数吗? - C++: Compiler instantiate template function only on demand? 在C ++中使用模板时,编译器如何知道要实例化多少个数据类型? - When using Templates in C++ how does the compiler know how many data-types to instantiate? C ++编译器不适用模板 - C++ compiler does not apply template 为什么C ++实例化一个被完全特化掩盖的基本模板函数? - Why does C++ instantiate a base template function which is masked by a full specialization? 为什么编译器会尝试实例化一个我实际上并没有在任何地方实例化的模板? - Why does the compiler try to instantiate a template that I don't actually instantiate anywhere? 当我们声明一个额外的模板参数而不在定义中使用时,为什么编译器会抛出错误? - Why does compiler throw an error when we declare an extra template argument and not used in definition? C ++为什么当不使用删除的功能时,编译器因错误代码C2280而失败 - C++ Why the compiler failed with the error code C2280 when the deleted function is not used 如何在C ++中实例化模板 - How to instantiate the template in C++
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM