std :: remove_reference有什么意义呢?

时间:2018-05-03 15:28:40

标签: c++ templates lambda reference c++14

让我深入研究C ++ 14通用lambdas:

var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = (_request,_certificate, _chain,_errors) => 
{
    Console.WriteLine(_request?.RequestUri.ToString() ?? "Request not defined");
    return true;
};

var client = new HttpClient(handler);
var request = new HttpRequestMessage(HttpMethod.Get, "https://google.com");
client.SendAsync(request);
client.GetAsync("https://google.com");

由于行#include <iostream> // g++ -std=c++14 template<typename T> T incr(T v) { return v + 1; } int main() { float f = 2.0; int i = 3; auto selfincr = [] (auto & value) { value = incr<std::remove_reference<decltype(value)>>(value); // A value = incr<decltype(value)>(value); // B }; selfincr(f); selfincr(i); std::cout << "f " << f << ", i " << i << std::endl; return 0; } 导致

  

从'T'类型的右值开始无效初始化'T&amp;'类型的非const引用

我的直接猜测是删除了引用,所以我添加了行// B。但这会产生一个

  

没有匹配函数来调用'incr(T&amp;)'

那我怎么能删除那个引用?

2 个答案:

答案 0 :(得分:9)

  

那我怎么能删除那个引用?

incr<std::remove_reference<decltype(value)>>(value),您指定std::remove_reference<T>作为模板参数,但不是T引用的类型(即decltype(value))。你想要的应该是

value = incr<typename std::remove_reference<decltype(value)>::type>(value);    // A
//           ~~~~~~~~                                       ~~~~~~        

从C ++ 14开始,你可以更简单:

value = incr<std::remove_reference_t<decltype(value)>>(value);    // A
//                                ~~ 

LIVE

答案 1 :(得分:2)

此:

value = incr<std::remove_reference<decltype(value)>>(value);    // A
由于songyuanyao解释了什么,

无法正常工作。

此:

value = incr<decltype(value)>(value);                           // B

没有工作因为decltype(value)是一种参考类型,而您正在尝试实例化:

float& incr(float& v) { return v + 1; }
int& incr(int& v) { return v + 1; }

您不能将这些表达式绑定到非const左值引用,因此编译错误。

最简单的解决方案就是让模板演绎能够做到:

value = incr(value); // C

根据需要调用incr<int>incr<float>