C++ 为什么'std::common\u type\u t<;标准::奥斯特雷姆公司;,标准::奥斯特雷姆公司>;`等于'std::ostream'而不是'std::ostream&;`?
我正在开发一个小型的库,我需要做的一件事是将访问者应用到一些数据并返回结果C++ 为什么'std::common\u type\u t<;标准::奥斯特雷姆公司;,标准::奥斯特雷姆公司>;`等于'std::ostream'而不是'std::ostream&;`?,c++,templates,c++11,stl,template-meta-programming,C++,Templates,C++11,Stl,Template Meta Programming,我正在开发一个小型的库,我需要做的一件事是将访问者应用到一些数据并返回结果 在一些旧的C++代码中,访问者期望声明一个 TyPulfReTurnType < /C>。例如,boost::static\u visitor就是这样做的 在较新的代码中,所有这些访问者都不推荐使用。在C++14中,您通常可以使用decltype(auto),但我尝试使用类似std::common_type的方法来实现,这样我就可以在C++11中实现 我尝试简单地将std::common_type的一个示例实现移植到C+
在一些旧的C++代码中,访问者期望声明一个<代码> TyPulfReTurnType < /C>。例如,
boost::static\u visitor
就是这样做的
在较新的代码中,所有这些访问者都不推荐使用。在C++14中,您通常可以使用decltype(auto)
,但我尝试使用类似std::common_type
的方法来实现,这样我就可以在C++11中实现
我尝试简单地将std::common_type
的一个示例实现移植到C++11,并使用它来计算返回类型
然而,当在上使用“可能的实现”时,我得到了一些意想不到的结果
#包括
#包括
//衰变后端口
模板
使用detacy\u t=typename std::detacy::type;
//公共_型后端口
模板
结构公共_类型;
模板
结构公共类型{
使用类型=衰减;
};
模板
结构公共类型{
使用类型=衰减;
};
//托多:需要这个吗?
/*
模板
结构公共类型{
使用类型=T;
};
*/
模板
结构公共类型{
使用type=typename公共类型::type;
};
模板
使用common_type_t=typename common_type::type;
//静态断言(std::is_same::value,“这就是我所期望的!”;
静态断言(std::is_same::value,“Hmm…”);
int main(){}
std::common\u type\t
的结果应该是什么?它是否应该是std::ostream&
?如果不是,那么为什么gcc5.4.0
和clang3.8.0
都认为它是std::ostream
注意:当我在C++14中使用“real”std::common\u type\t
时,我仍然得到std::ostream
,而不是std::ostream&
专业化std::common_type
是否使std::common_type_t
始终是t
一种有效的方法?在我的程序中,它似乎工作得很好,但感觉像是一个黑客。有关常见类型的历史以及为什么它实际上没有产生引用的相关讨论,请参阅
专业化std::common_type
是否使std::common_type_t
始终是一种有效的方法
我假定您的意思是专门化通用类型的实现(因为您不能专门化另一个)。不,这还不够。您可能希望common\u type
成为Base&
,但该实例化不会经过您的专门化
您真正想要的是不要使用衰减
。衰减
存在的原因是为了删除在某些情况下declval
提供的意外右值引用。但是您希望维护左值引用-因此只需添加您自己的类型特征:
template <class T>
using common_decay_t = std::conditional_t<
std::is_lvalue_reference<T>::value,
T,
std::remove_reference_t<T>>;
模板
使用公共衰减=标准::条件衰减<
std::is_lvalue_reference::value,
T
标准::删除参考文件;
用它来代替正常的衰退
相关:,但是是的普通类型
不会给你推荐信,因为你的脸很悲伤。谢谢你。。。所以我想我不应该在那里使用std::declval
?我应该使用decltype(true?std::forward(std::declval()):std::forward(std::declval())
?我想这实际上是相当棘手的…我想我现在正在使用这个版本,但我会将您的答案标记为正确:模板使用mini_detacient\u t=conditional\u t代码>
template <class T>
using common_decay_t = std::conditional_t<
std::is_lvalue_reference<T>::value,
T,
std::remove_reference_t<T>>;