【问题标题】:Passing template type parameter as a type of template non-type parameter将模板类型参数作为模板非类型参数的类型传递
【发布时间】:2019-04-24 22:12:29
【问题描述】:

只是好奇:在 C++17 及更高版本中,我们可以为非类型模板参数使用 auto 占位符:

template<typename A, auto B>
class C {
public:
    A foo() { return B; }
};

但是我们可以传递模板类型参数A而不是auto吗?

example.cpp

template<typename A, A B>
class C {
public:
    A foo() { return B; }
};

int main()
{
    C<int, 5> c;
    std::cout << c.foo() << std::endl;

    return 0;
}

在实践中我们可以,并且使用 -std=c++11 可以做到这一点。

$ g++ -std=c++11 example.cpp
$ ./a.out
5

但是标准呢?我没有找到任何明确的规则。 谢谢!

【问题讨论】:

  • 我认为这是可能的,除了字符串文字。 See this
  • 我已对您的问题进行了编辑,以包含语言律师标签。这应该会吸引您正在寻找的人群(即对标准的引用)。

标签: c++ c++11 templates language-lawyer c++17


【解决方案1】:

模板参数可以分为:

1. Type parameters
2. Non type parameters
3. Template template parameters

在您的情况下,语句A B 是一个非类型模板参数,其类型是模板类型参数A

请记住,在您的示例中,您会这样做:

return B;

上面的语句在类型 A 不是 copy constructible 上会失败(这很容易用一个概念来表达)。

请记住(正如 cmets 中所指出的那样),C++17 要求复制省略。

【讨论】:

  • "在你的例子中,语句 A B 是一个非类型模板参数,其类型是模板类型参数 A。"我知道。整个问题是否符合标准。
  • @StepanDyatkovskiy 因为它命名了一个特性,即一个非模板参数,为什么不呢?我可以稍后再看一下标准,但如果不是这样,我会感到惊讶。
  • 在 C++17 中,return B 不要求 A 可以复制或移动构造,因为 mandatory copy/move elision 是纯右值。
  • @Oktalist 我已经写好了(如果你看到了编辑的历史),但我删除了它以缩小范围。你提到它应该放在那里以避免混淆。感谢您指出。 (即使不能保证 C++17 之前的复制省略,我知道的大多数编译器都会省略复制)
  • 在 C++17 之前,移动或复制构造函数仍然需要,即使它被省略了。
【解决方案2】:

但是我们可以传递而不是左侧定义的“auto”模板类型参数吗?

当然。这是老办法。

auto 方式允许避免传递A 类型。

在 C++17 中你可以编写

template <auto B>
class C {
public:
    auto foo() { return B; }
};

所以不需要传递类型A

我不知道如何在 C++11/C++14 中做同样的事情。

我的意思是:如果需要,在 C++11/C++14 中将值传递给模板...如果类型是固定的,则没有问题

template <int I>

但类型本身可以不同,在 C++11/C++14 中,您必须先传递类型,然后传递 example.cpp 中的值

template <typename T, T A>

问题是,如果你想调用那种类型的模板,你必须是多余的,写一些东西为

C<decltype(x), x>  some_C_variable;

我知道避免这种冗余的唯一方法是通过 make 函数(类似于 make_tuple())或 C 风格的宏。

在 C++17 中,您可以简单地编写

C<x>   some_C_variable

并且,在C模板类/结构中,x的类型可以从decltype(B)获取。

对于 C++17 标准参考...

首先,auto 被定义为“placeolder”

从 10.1.7.4(auto 说明符)开始,第 1 点

autodecltype(auto) 类型说明符用于指定占位符类型,稍后将通过初始化程序的推导来替换。

在 C++11/C++14 中也是如此

但 C++17 标准添加,对于“模板参数”(17.1),在第 4 点枚举中,新的第 4.6 点

  1. 非类型 模板参数 应具有以下类型之一(可选 cv 限定):

[...]

(4.6) 包含占位符类型的类型 (10.1.7.4)

【讨论】:

  • 谢谢!您是否知道任何标准参考,或者只是链接到描述这种可能性的 cppreference?
  • @StepanDyatkovskiy - 我不是语言律师,所以我很难找到确切的参考资料;对于 cppreference,您可以看到 auto page(参见第 8 点)
  • @StepanDyatkovskiy - 添加了几个 C++17 标准参考;希望对您有所帮助。
猜你喜欢
  • 1970-01-01
  • 2016-10-20
  • 2021-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-06
相关资源
最近更新 更多