【问题标题】:Is it possible to perfect forward a template template parameter是否可以完善转发模板模板参数
【发布时间】:2016-03-01 00:40:28
【问题描述】:

我知道如何完善转发参数。但是,我从不同的来源(例如 Effective Modern C++ Item 24 - Scott Meyers)读到,只有当您拥有确切的模板名称时,才能完美转发,例如:

template<typename T>
void foo(T&& param) { bar(std::forward<T>(param)); }

我正在寻找的是是否有一种方法可以完善转发模板模板参数,例如:

template<template<int, class TypeT> class Vector, int Size, typename TypeT>
void foo(Vector<Size, TypeT>&& param) { bar(std::forward<Vector<Size, TypeT>>(param)); }

当我编译上述内容时,我收到一条错误消息:“您无法将左值绑定到右值引用”(VC12),这表明编译器无法将 && 识别为“通用引用”,而是作为一个右值引用。这种完美的转发可能对我有用,因为我可以利用推断的 TypeT 和 Size。

问题:是否可以完善转发模板模板参数?如果是这样,我的语法在哪里不正确?

谢谢!

【问题讨论】:

  • 没有。你需要带上T&amp;&amp;,然后再检查std::decay_t&lt;T&gt;
  • 你也可以做 2 个重载,一个用于 r-value,一个用于 l-value。

标签: c++ perfect-forwarding template-templates


【解决方案1】:

“通用引用”(标准术语是转发引用)是(根据定义)对 cv 非限定模板参数的右值引用,即T&amp;&amp;

Vector&lt;Size, TypeT&gt;&amp;&amp; 是右值引用,而不是转发引用。

如果你想获取模板参数的值,写一个 trait:

template<class> struct vector_traits;

template<template<int, class TypeT> class Vector, int Size, typename TypeT>
struct vector_traits<Vector<Size, TypeT>>{
    static constexpr int size = Size;
    using value_type = TypeT;
};

并检查std::decay_t&lt;T&gt;

template<class T>
void foo(T&& t) {
    using TypeT = typename vector_traits<std::decay_t<T>>::value_type;
    // use TypeT.
}

您还可以将其移至默认模板参数,这使foo SFINAE 友好(如果std::decay_t&lt;T&gt; 不是“向量”,则从重载集中删除):

template<class T,
         class TypeT = typename vector_traits<std::decay_t<T>>::value_type>
void foo(T&& t) {
    // use TypeT.
}

【讨论】:

    猜你喜欢
    • 2011-09-23
    • 1970-01-01
    • 1970-01-01
    • 2013-01-06
    • 2019-02-22
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多