我正在研究一个小型图书馆,我需要做的事情之一是将访问者应用于某些数据并返回结果。为什么`std :: common_type_t <std :: ostream&,std :: ostream&>`等于`std :: ostream`而不是`std :: ostream&`?
在一些较旧的C++代码中,访问者预计会声明一个typedef return_type
。例如,boost::static_visitor
这样做。
在较新的代码中,所有这些访问者都被弃用。在C++ 14中,您通常可以使用decltype(auto)
,但我正在尝试使用类似std::common_type
的东西来做到这一点,以便我可以在C++ 11中执行此操作。
我试着简单地将std::common_type
的示例实现反向移植到C++ 11并使用它来计算返回类型。
#include <ostream>
#include <type_traits>
// decay_t backport
template <typename T>
using decay_t = typename std::decay<T>::type;
// common_type backport
template <typename T, typename... Ts>
struct common_type;
template <typename T>
struct common_type<T> {
using type = decay_t<T>;
};
template <typename T1, typename T2>
struct common_type<T1, T2> {
using type = decay_t<decltype(true ? std::declval<T1>() : std::declval<T2>())>;
};
// TODO: Is this needed?
/*
template <typename T>
struct common_type<T, T> {
using type = T;
};
*/
template <typename T1, typename T2, typename T3, typename... Ts>
struct common_type<T1, T2, T3, Ts...> {
using type = typename common_type<typename common_type<T1, T2>::type, T3, Ts...>::type;
};
template <typename T, typename... Ts>
using common_type_t = typename common_type<T, Ts...>::type;
// static_assert(std::is_same<common_type_t<std::ostream &, std::ostream &>, std::ostream &>::value, "This is what I expected!");
static_assert(std::is_same<common_type_t<std::ostream &, std::ostream &>, std::ostream>::value, "Hmm...");
int main() {}
使用“可能实现”的时候什么“应该”的std::common_type_t<std::ostream&, std::ostream&>
的结果是我得到一些意想不到的结果?它应该不是std::ostream &
?如果没有,那么为什么gcc 5.4.0
和clang 3.8.0
认为它是std::ostream
?
注意:当我在C++ 14中使用“真实”std::common_type_t
时,我仍然得到std::ostream
而不是std::ostream &
。
正在专精std::common_type
这样std::common_type_t<T, T>
总是T
有效的方法吗?它似乎在我的程序中运行良好,但感觉像是一个黑客。
相关:http://stackoverflow.com/q/21975812/2069064,但是'common_type'不会给你引用,因为悲伤的脸。 – Barry
谢谢...所以我想我不应该在那里使用'std :: declval'?我应该使用'decltype(true?std :: forward(std :: declval ()):std :: forward (std :: declval ())''?我想这实际上很棘手... –