我知道如何完善转发参数。但是,我从不同的来源(例如,有效的现代C ++第24项 - 斯科特迈耶斯)中读到,当你有确切的模板名称时,人们只能完美地前进,例如:
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)); }
当我编译上面的内容时,我收到一条错误消息:&#34;你不能将左值绑定到右值引用&#34; (VC12),它告诉我编译器不能识别&amp;&amp;作为&#34;普遍参考&#34;但作为右值参考。这个完美的前锋对我有用,因为我可以利用推断出的TypeT和Size。
问题:是否可以完善转发模板模板参数?如果是这样,我的语法在哪里不正确?
谢谢!
答案 0 :(得分:5)
“通用引用”(标准术语是转发引用)是(根据定义)对cv非限定模板参数的右值引用,即T&&
。
Vector<Size, TypeT>&&
是一个右值引用,而不是转发引用。
如果要获取模板参数的值,请写一个特征:
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>
不是“向量”,则从过载集中删除):
template<class T,
class TypeT = typename vector_traits<std::decay_t<T>>::value_type>
void foo(T&& t) {
// use TypeT.
}