为什么reference_wrapper对于内置类型的行为有所不同?

阿尔法

std::reference_wrapper对构建类型(double)和用户定义的类型(std::string有以下用途

为什么在流运算符的情况下它们的行为有所不同?

#include<functional> //reference wrapper
#include<iostream>

void fd(double& d){}
void fs(std::string& s){}

int main(){

   double D = 5.;
   std::reference_wrapper<double> DR(D);
   std::cout << "DR = " << DR << std::endl; //ok 
   fd(DR); // ok

   std::string S = "hello";
   std::reference_wrapper<std::string> SR(S);
   std::cout << "SR = " << static_cast<std::string&>(SR) << std::endl; // ok
   std::cout << "SR = " << SR << std::endl; // error: invalid operands to binary expression ('basic_ostream<char, std::char_traits<char> >' and 'std::reference_wrapper<std::string>')
   fs(SR); // ok 
}

http://coliru.stacked-crooked.com/a/fc4c614d6b7da690

为什么在第一种情况下将DR转换为double并打印,而在第二种情况下却没有呢?有没有解决的办法?


好的,我现在看到的是,在ostream情况下,我试图调用无法解析的模板化函数:

#include<functional> //reference wrapper

void double_fun(double const& t){};

template<class C>
void string_fun(std::basic_string<C> const& t){};


int main(){

   double D = 5.;
   std::reference_wrapper<double> DR(D);
   double_fun(DR); //ok

   std::string S = "hello";
   std::reference_wrapper<std::string> SR(S);
   string_fun(SR); // error: no matching function for call to 'string_fun'
   string_fun(SR.get()); // ok
   string_fun(static_cast<std::string&>(SR)); // ok
   string_fun(*&SR); // would be ok if `std::reference_wrapper` was designed/coded differently, see http://stackoverflow.com/a/34144470/225186
}
101010

对于第一部分,TC给了您答案。也就是说,basic_string的operator <<是模板化的,并且模板参数推导不会通过隐式转换进行查找。

SR.get()如果您不想显式static_cast引用引用包装器,可以选择调用

现在,对于第二部分,string_funstd::basic_string<C>对象作为输入参数你打电话时:

string_fun(SR);

SR作为它的类型的输入参数std::reference_wrapper<std::string>,自然你就会得到一个类型不匹配。

您可以做的是提供额外的重载:

template<class C>
void string_fun(std::reference_wrapper<std::basic_string<C>> const& t) {

};

现场演示

或者,如果您想要更统一的处理方式,则可以定义您的string_fun模板模板参数,并使用类似下面的类型特征魔术来解析类型:

template<template<typename...> class C, typename T>
void
string_fun(C<T> const &t) {
  std::cout << 
    static_cast<std::conditional_t<
      std::is_same<
        std::reference_wrapper<T>, C<T>>::value, T, std::basic_string<T>>>(t) << std::endl;
}

现场演示

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么在使用ICustomTypeDescriptor时TypeDescriptor.GetProperties对于类型和对象的行为会有所不同

为什么ContextMenuOpening的Source对于Canvas和UserControl的行为有所不同?

为什么对于相同但按比例缩放的数据,绘图的行为会有所不同?

为什么`-lt`对于字符和字符串的行为有所不同?

为什么hasOwnProperty对于构造函数和实例的行为有所不同?

为什么hide()的行为有所不同?

为什么numpy导入的行为有所不同?

为什么to_sym的行为有所不同?

为什么groupby操作的行为有所不同

为什么当类型实现接口时,行为会有所不同?

为什么在存在类型参数默认值的情况下,类型推断对于“ HashMap”和我自己的结构的行为有所不同?

在此示例中,为什么max()函数对于两个属性的行为有所不同?

为什么空条件运算符对于==和.Equals()的行为会有所不同?

为什么Python范围对于列表变量和字符串变量的行为似乎有所不同?

为什么参数的行为对于字符串数组和整数数组会有所不同?

提供通用类型与直接类型时,为什么Typescript映射元组类型的行为会有所不同?

对于MSIE 10上的行为有所不同

TraitCollectionDidChange对于iPhone X的行为有所不同

为什么ANativeWindow_Buffer.stride对于不同的设备有所不同

<|>在Parsec中-为什么这些示例的行为有所不同?

当类中的counter较大时,为什么java线程的行为会有所不同?

为什么在此示例中,“ grep”的行为有所不同?

为什么“花括号”在JavaScript中的行为有所不同?

为什么中断和isInterrupted的行为方式有所不同?

为什么这些小型D程序的行为有所不同?

为什么`Paths.get`方法的行为有所不同?

当类在函数内时,为什么类中的全局行为会有所不同?

为什么这些生成器表达式的行为有所不同?

为什么bash的脚本与stdin的行为有所不同?