转发引用和模板模板
Forwarding references and template templates
考虑这两个模板函数:
template<typename T>
void foo(T&& bar) {
// do stuff with bar, which may or may not be an instance of a templated class
}
template<typename U, template<typename> class T>
void foo(T<U>&& bar) {
// do stuff with bar, which must be an instance of a templated class
}
为什么前者接受左值(通过使用转发引用)而后者不接受?
看起来身份别名模板可以作为转发引用吗? 可能也与此有关,但它似乎涵盖了转发引用限制的不同方面。
如果要保留转发引用参数,同时推断参数的类型,则可以使用以下解决方案:
#include <type_traits>
#include <utility>
template <typename T>
struct tag {};
template <typename T, typename U, template <typename> class C>
void foo(T&& t, tag<C<U>>)
{
}
template <typename T>
auto foo(T&& t)
-> decltype(foo(std::forward<T>(t), tag<typename std::decay<T>::type>{}))
{
return foo(std::forward<T>(t), tag<typename std::decay<T>::type>{});
}
演示
因为这就是标准所说的语言应该工作的方式。
[14.8.2.1][温度扣除调用]
3.如果P是符合CV条件的类型,则忽略P类型的顶级CV限定符进行类型推断。如果 P 是 参考类型,P所指的类型用于类型推导。转发引用是右值 对 CV 非限定模板参数的引用。如果 P 是转发引用,并且参数是 lvalue,类型"对 A 的左值引用"用于代替 A 进行类型扣除。
只有对 CV 非限定模板参数的右值引用才能以这种方式推导出为 l 值引用。
要实现您尝试执行的操作,您可能能够使用特征来提取模板模板参数。
#include <type_traits>
/***
* Extract template from template type.
*/
template <typename I> struct get_template;
template <template<class> typename T, typename C>
struct get_template<T<C>> {
template <typename U>
using temp = T<U>;
};
template <typename T> struct A{};
struct B;
template<typename W>
void foo(W && bar) {
typedef typename get_template<typename std::remove_reference<W>::type>::template temp<int> new_type;
new_type my_variable;
}
int main() {
A<B> temp;
foo(temp);
}
或者,像往常一样重载 const 和 && 的函数。
相关文章:
- 正在折叠转发引用
- 如何在模板中转发右值和左值引用
- 通过基类接受方法转发派生 UniquePtr 的右值会移动引用而不是复制
- C++ 何时使用常量引用而不是转发引用
- 为什么转发声明的好友类不能在类中引用?
- C++完美转发:如何避免悬空引用
- C++:通用(转发)引用中不允许常量
- 模板模板参数和转发引用
- 常量转发引用给出错误 C2440:"正在初始化":无法从"常量标准::字符串"转换为"常量标准::字符串 &&"
- 具有右值引用,而不是使用可变参数模板转发引用
- 自定义类型转换运算符在转发引用上调用时不起作用(当对象按值传递时有效)
- 如何从常量引用或通过转发模板临时构造对象
- 结构化绑定和转发引用是否混合良好?
- 如何声明接受转发引用并返回引用或副本的函数模板
- 间接转发引用
- 为什么调用转发引用构造函数而不是复制构造函数?
- 为什么 std::get 没有一个接受转发引用的签名
- 有没有办法在不引用其模板类型的情况下转发声明指向类的指针
- c++重新评估引用转发性能
- 右值引用转发错误