簡體   English   中英

C ++:為什么編譯器在不使用模板時將其實例化

[英]C++: Why does the compiler instantiate a template when it is not used

讓我們考慮以下代碼:

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);
}

當我嘗試對此進行編譯時,出現以下錯誤:

error: no type named 'type' in 'struct std::enable_if<false, void>'

但是當參數<bool c>false時,我不使用模板方法f(int) ,那么它不應該存在。

您似乎不正確地相信編譯器不會“實例化”您的模板。 編譯器只是在嘗試解析和分析模板聲明,這是類定義的一部分。 如果實例化該類,則所有成員聲明都必須有效。 您的成員模板聲明無效。 因此,錯誤。

如果某些模板“未使用”,則意味着它不會被專門化和實例化。 但是該模板的聲明仍然必須有效。 並立即檢查不依賴模板參數的那些聲明部分的有效性。 換句話說,您在代碼中編寫的內容與

template <typename T = jksgdcaufgdug> void foo() {}

int main() {}

或者,更貼近您的情況

template <typename T = std::enable_if<false>::type> void foo() {}

int main() {}

即使這些程序不“使用”(不實例化)功能模板foo ,也並不意味着foo的聲明可以包含jksgdcaufgdug類的隨機垃圾,也jksgdcaufgdug明確引用諸如std::enable_if<false>::type類的不存在的實體std::enable_if<false>::type 由於上述原因,以上示例將無法編譯。

您可以在相關上下文中使用“隨機垃圾”,例如

template <typename T> void foo(typename T::kjhdfjskhf x) 
{ 
  typename T::jksgdcaufgdug i; 
}

並且您可以在類似的依賴上下文中使用std::enable_if

template <typename T, 
          typename U = typename enable_if<is_void<T>::value>::type>
void bar()
{ 
}

並且不會產生“早期”錯誤,但是在您的情況下, enable_if<c>不依賴於Temp ,因此它不在依賴上下文中。 這意味着實例化A<false>時會立即檢查typename enable_if<c>::type名稱typename enable_if<c>::type的正確性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM