저는 작은 도서관에서 일하고 있습니다. 제가해야 할 일 중 하나는 방문객을 일부 데이터에 적용하고 결과를 반환하는 것입니다.`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로 간단히 백 포트하여 리턴 유형을 계산하는 데 사용했습니다. std::common_type_t<std::ostream&, std::ostream&>
의 결과가 될 "해야"무엇 cppreference.com
#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::ostream &
이 아니어야합니까? 그렇지 않다면 과 clang 3.8.0
이 모두 std::ostream
이라고 생각하십니까?
참고 : C++ 14에서 "진짜"std::common_type_t
을 사용할 때 나는 여전히 std::ostream
이 아니라 std::ostream &
이 아닙니다.
이 항상 유효한 방법이되도록 std::common_type
을 전문화합니까? 그것은 내 프로그램에서 잘 작동하는 것 같지만 해킹처럼 느껴집니다.
관련 : http://stackoverflow.com/q/21975812/2069064,하지만'common_type'은 슬픈 표정 때문에 참조를 제공하지 않습니다. – Barry
고맙습니다 ... 그래서 나는'std :: declval'을 사용해서는 안된다고 생각하십니까? 'decltype (true? std :: forward (std :: declval ()) : std :: forward (std :: decl())')을 사용해야합니까? 사실이게 꽤 까다 롭습니다.'템플릿 을 mini_decay_t = conditional_t < 표준 : is_lvalue_reference :: 값을 사용하여 : –