命名模板静态 class 方法的特定实例的语法

Syntax for naming a specific instance of a template static class method

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

以下所有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>;
};

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

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

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

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

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

请注意这里的 g1 不是 f<1> -- 例如 &S::f<1> != &S::g1。但是调用它具有相同的效果。 (对于某些链接器,这可能不是真的;msvc 链接器或 gold 链接器设置激进)

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

f() 不是 class。这是一种方法。 类,各种类型,这种性质的东西,可以别名为usingtypedef。但不是函数或方法。

如果要特化 class 方法,请在 class 之外定义方法的特化:

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

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

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

因此,调用 f1() 现在会调用专用方法。

如果您既想特化又想 "alias" 静态 class 方法,还有一个额外的变化。您不能在 class 中内联定义包装器。这是因为尚未声明专业化。您必须声明包装器;定义好专业后再定义:

#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,以避免在 link 时出现重复符号。如果整个事情进入一个翻译单元,你可以删除 inline.

这个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&我们命名具体的模板函数实例化