是否可以完美转发模板模板参数
Is it possible to perfect forward a template template parameter
我知道如何完美转发一个参数。然而,我从不同的来源(例如 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)); }
当我编译上面的代码时,我收到一条错误消息:"You cannot bind an lvalue to an rvalue reference" (VC12),这表明编译器不将 && 识别为 "universal reference",而是将其识别为右值引用.这种完美的转发可能对我有用,因为我可以利用推导的 TypeT 和 Size。
问题:是否可以完善forward template模板参数?如果是这样,我的语法哪里不正确?
谢谢!
A "universal reference"(标准术语是 转发引用)(根据定义)是对 cv 不合格模板参数的右值引用,即 T&&
.
Vector<Size, TypeT>&&
是右值引用,不是转发引用。
如果要获取模板参数的值,写一个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<T>
:
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<T>
不是 "vector",它会从重载集中删除):
template<class T,
class TypeT = typename vector_traits<std::decay_t<T>>::value_type>
void foo(T&& t) {
// use TypeT.
}
我知道如何完美转发一个参数。然而,我从不同的来源(例如 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)); }
当我编译上面的代码时,我收到一条错误消息:"You cannot bind an lvalue to an rvalue reference" (VC12),这表明编译器不将 && 识别为 "universal reference",而是将其识别为右值引用.这种完美的转发可能对我有用,因为我可以利用推导的 TypeT 和 Size。
问题:是否可以完善forward template模板参数?如果是这样,我的语法哪里不正确?
谢谢!
A "universal reference"(标准术语是 转发引用)(根据定义)是对 cv 不合格模板参数的右值引用,即 T&&
.
Vector<Size, TypeT>&&
是右值引用,不是转发引用。
如果要获取模板参数的值,写一个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<T>
:
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<T>
不是 "vector",它会从重载集中删除):
template<class T,
class TypeT = typename vector_traits<std::decay_t<T>>::value_type>
void foo(T&& t) {
// use TypeT.
}