Mentre la codifica in giro in un progetto su cui sto lavorando, ho scoperto qualcosa di veramente strano:perché non si può risolvere questo gcc utilizzando dichiarazione al tipo corretto
namespace detail {
struct tuplelike_tag { };
struct arraylike_tag { };
template<typename>
struct call_with_traits;
template<typename... Ts>
struct call_with_traits<std::tuple<Ts...>> {
using tag = tuplelike_tag;
enum { size = sizeof...(Ts) };
};
template<typename T, std::size_t Sz>
struct call_with_traits<std::array<T, Sz>> {
using tag = arraylike_tag;
enum { size = Sz };
};
template<typename T, std::size_t Sz>
struct call_with_traits<T[Sz]> {
using tag = arraylike_tag;
enum { size = Sz };
};
template<typename F, typename T, int... Is>
auto call_with(F && f, T && tup, indices<Is...>, tuplelike_tag) -> ResultOf<Unqualified<F>> {
return (std::forward<F>(f))(std::get<Is>(std::forward<T>(tup))...);
}
template<typename F, typename A, int... Is>
auto call_with(F && f, A && arr, indices<Is...>, arraylike_tag) -> ResultOf<Unqualified<F>> {
return (std::forward<F>(f))(std::forward<A>(arr)[Is]...);
}
}
template<typename F, typename Cont>
inline auto call_with(F && f, Cont && cont) -> ResultOf<Unqualified<F>> {
using unqualified = Unqualified<Cont>;
using traits = typename detail::call_with_traits<unqualified>;
using tag = typename detail::call_with_traits<unqualified>::tag;
using no_tag = typename traits::tag; // this is what it's all about
return detail::call_with(std::forward<F>(f), std::forward<Cont>(cont), build_indices<traits::size>(), tag());
}
La cosa strana di questo codice è che il tag viene risolto in dettaglio nome :: call_with_traits :: tag;, ma no_tag errori fuori:
error: no type named ‘tag’ in ‘using traits = struct detail::call_with_traits<typename std::remove_cv<typename std::remove_reference<_To>::type>::type>’
anche se dovrebbe fare riferimento alla stessa dichiarazione utilizzando nella stessa struct. C'è qualcosa che mi manca, o questo è un bug in GCC?
A live example can be found here, incluso il relativo messaggio di errore da GCC.
Direi che è un bug. Compilano bene su GCC 4.8.0 e su Clang 3.2 –