【问题标题】:Force template instantiation via typedef template<typename T, T> - why it works?通过 typedef template<typename T, T> 强制模板实例化 - 为什么它有效?
【发布时间】:2019-09-16 06:39:38
【问题描述】:

我正在学习强制模板实例化。
它有效,但我仍然很好奇:-

#include <iostream>
#include <string>
template <typename T, T>struct NonTypeParameter { };//#1#
int lala=0;
template <typename T> class InitCRTP{
    public: static int init;
    public: using dummy=NonTypeParameter<int&, init>;   //#2#
};
template <typename T> int InitCRTP<T>::init = lala++;
class WantInit : public InitCRTP<WantInit>{
};
int main(){
    std::cout << lala << std::endl;
}

它打印 1,因为 InitCRTP&lt;WantInit&gt;::init 已正确实例化。

观察

  1. 如果我删除#2# 行,它将打印0。(InitCRTP&lt;WantInit&gt;::init 未实例化)。
  2. 如果我将 #2#int&amp; 更改为 int,我会得到:-

    错误:'InitCRTP::init' 的值不能用于常量 表达

  3. 如果我将#1# 更改为template &lt;T&gt;struct NonTypeParameter { }; 并将#2# 更改为public: using dummy=NonTypeParameter&lt;init&gt;;,我将得到:-

    错误:'T' 尚未声明

问题

  1. 为什么#2# 行足以强制实例化?
    在我看来,它只是模板类中的 typedef ,任何人都无法访问。

  2. 为什么我需要int&amp; 作为另一个模板参数才能使其可编译?
    一个可能更正确的问题:该技术的名称是什么?

原帖:Force explicit template instantiation with CRTP

【问题讨论】:

    标签: c++ crtp template-instantiation


    【解决方案1】:

    为什么 #2# 行足以强制实例化?

    为了提供第二个参数,编译器必须绑定一个引用。这意味着它 ODR-使用静态变量,因此该变量必须存在并且具有唯一的标识。因此,它的定义是实例化的。

    当你使用普通的int 时,第二个参数只能接受整数常量表达式。非常量静态不能在常量表达式中使用。

    为什么我需要int&amp; 作为另一个模板参数才能使其可编译?

    您需要为第二个参数声明引用的类型,以使其具有编译器可以检查的类型。好吧,在 C++17 之前,无论如何你都需要这样做。现在我们可以使用占位符类型。

    template <auto&>struct NonTypeParameter { };//#1#
    using dummy=NonTypeParameter<init>;//#2#
    

    这将 ODR 使用传入的静态,而无需显式指定引用类型。

    【讨论】:

    • 谢谢。不错的答案。你碰巧对奇怪的行为“Ergo,它的定义被实例化”有一些参考吗?
    • 谢谢,您在另一篇关于timsong-cpp.github.io/cppwp/n4659/temp.inst#2 的帖子中引用的内容让我安息。
    • @StoryTeller:您如何看待 [temp.inst]/2–3 的明显含义,即不应急切实例化这样的成员类型别名?
    • @DavisHerring - 我提出了措辞问题。它不应该只是表面上暗示任何一种方式。我属于同意 GCC 和 Clang 实施的阵营。是否正确应该明确说明
    • @StoryTeller:对我来说,这似乎与 CWG2335 有关,因为可以“根据需要”实例化这些东西。当然,总是可以通过使用类型别名的成员声明来强制“需要”部分。同时,您可能会感兴趣看到基于肯定实例化的alternative I concocted
    猜你喜欢
    • 2011-05-30
    • 2013-04-05
    • 1970-01-01
    • 2017-06-22
    • 2021-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多