【问题标题】:Syntax for naming a specific instance of a template static class method命名模板静态类方法的特定实例的语法
【发布时间】:2017-01-16 16:36:07
【问题描述】:

命名模板静态方法的特定实例的正确语法是什么?

以下所有attempts 似乎都是错误的:

struct S
{
    template<int x> static int f() { return x; }
    using g1 = f<1>;
    template using g2 = f<1>;
    template<> using g3 = f<1>;
};

【问题讨论】:

  • using 命名一个类型。函数不是类型。 f&lt;1&gt; 是一个函数。你能解释一下你想要这个命名做什么,以及你想如何使用它吗?假设您有static int f_1() { return 1; },请说明您想用它而不是f&lt;1&gt; 做什么以及如何做。
  • @Yakk 我感兴趣的不是命名类型,而是用某个名称(比如 g)命名 f,以便稍后我可以调用 g() 而不是 f ,目的是 DRY,以防对函数模板的这个特定实例化有很多调用。有可能(合理的,按照你写的) using 不是这个工具;我该怎么做?
  • 如果你想要一个 变量 可以保存 value f&lt;1&gt;,只需使用 auto:auto g = f&lt;1&gt;
  • @Caleth 是的,这行得通。虽然必须在结构定义之外。 melpon.org/wandbox/permlink/LZ15s9WTlPEEKexL欢迎您将其发布为答案。
  • @Caleth 不过,如果能够命名特定的实例而不实际将其分配给变量,那就太好了。

标签: c++ c++11 templates using


【解决方案1】:

C++ 不喜欢具有模板方法的本地结构(请参阅here

你需要把它拿出来。您还想为您的 typedef 使用 decltype 吗?例如

typedef decltype(f<0>) t;
using g1 = decltype(f<0>);

那些只会给你类型。可能最好直接打电话给他们,例如S::f 等

【讨论】:

    【解决方案2】:
    struct S {
      template<int x> static int f() { return x; }
      static int g1() { return f<1>(); }
    };
    

    注意这里的g1 不是f&lt;1&gt; -- 例如&amp;S::f&lt;1&gt; != &amp;S::g1。但是调用它具有相同的效果。 (对于某些链接器,这可能不是真的;msvc 链接器或黄金链接器设置积极)

    【讨论】:

      【解决方案3】:

      using 定义了一个别名,它没有专门化任何东西。 using 为类、类型等定义别名...别名和特化是完全不同的两件事。

      f() 不是一个类。这是一种方法。类、各种类型和具有这种性质的事物可以使用usingtypedef 进行别名。但不是函数或方法。

      如果要特化类方法,请为类外的方法定义特化:

      template<>
      int S::f<1>()
      {
          return 0; // Or whatever your specialization function needs to do.
      }
      

      如果你想要一个函数的别名,这基本上是一个包装器:

      int f1()
      {
          return f<1>();
      }
      

      所以,调用f1() 现在调用专用方法。

      如果您想对静态类方法进行专门化和“别名化”,还有一个额外的转折点。您不能在类中定义包装器内联。这是因为尚未声明专业化。您必须声明包装器;然后在定义特化之后再定义:

      #include <iostream>
      
      struct S
      {
          template<int x> static int f() { return x; }
          static int f1();
      };
      
      template<>
      int S::f<1>()
      {
          return 0;
      }
      
      inline int S::f1()
      {
          return f<1>();
      }
      
      int main()
      {
          std::cout << S::f<4>() << std::endl;
          std::cout << S::f<1>() << std::endl;
      }
      

      inline 如果这实际上进入头文件,则需要,以避免在链接时出现重复符号。如果整个内容进入一个翻译单元,您可以删除inline

      【讨论】:

      • using f2=f&lt;1&gt; 无法编译
      • 寻找一种不涉及包装的方式。只是想命名一个特定的模板方法实例化。使用包装方法会起作用,但如果有例如更多尚未实例化的参数
      【解决方案4】:

      这个works

      #include <iostream>
      
      struct S {
          template<int x> static int f() { return x; }
      };
      
      auto& g = S::f<1>;
      
      int main() {
          std::cout << g() << std::endl;
          return 0;   
      }
      

      通过使用auto&amp;我们命名具体的模板函数实例化。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-30
        • 1970-01-01
        • 1970-01-01
        • 2010-09-14
        • 1970-01-01
        • 1970-01-01
        • 2018-03-07
        • 2011-11-10
        相关资源
        最近更新 更多