Poniższa funkcja derefItemX()
jest kompilowany na GCC 4.8-5.3 porządku, ale nie na Clang 3.8:Clang nie skompilować funkcję szablonu w specjalizacji klasy szablon, który ma odrębny typ zwracany * * od deklaracji szablonu
//! Accessory Operations - template argument depended wrappers
template<bool SIMPLE> // For Nodes/non-scoped storage
struct Operations {
//! \brief Defererence wrapped or direct iterator
//!
//! \param iel IItemXT& - iterator to be dereferenced
//! \return ItemT& - resulting reference
template<typename IItemXT>
constexpr static auto& derefItemX(IItemXT& iel)
{
static_assert(is_base_of<std::forward_iterator_tag, typename IItemXT::iterator_category>::value
, "derefItemX(), IItemXT must be a forward iterator type");
return **iel; // Dereference an iterator of pointer to the value
}
};
//! Specialization for non-scoped storage (direct pointers)
template<>
template<typename IItemXT>
constexpr auto& Operations<true>::derefItemX(IItemXT& iel)
{
static_assert(is_base_of<std::forward_iterator_tag, typename IItemXT::iterator_category>::value
, "derefItemX(), IItemXT must be a forward iterator type");
return *iel; // Dereference an iterator of value to the value
}
...
// Usage:
auto& el = Operations<!is_pointer<typename IItemXT::value_type>
::value>::derefItemX(ic);
derefItemX()
odejmuje iterator wartości lub wskaźnika do wartości początkowej. Dzyń pojawi się następujący komunikat o błędzie: który mówi niewiele:
include/hierarchy.hpp:168:35: error: out-of-line definition of 'derefItemX' does not match any declaration in 'XXX::Operations<true>'
constexpr auto& Operations<true>::derefItemX(IItemXT& iel)
^~~~~~~~~~
Czy ktoś proszę wyjaśnić:
- Dlaczego Clang nie skompilować
derefItemX()
? - Jak sparametryzować dereferencję iteratora na * x lub ** x używając innej metody, która działałaby na różnych kompilatorach?
Wielkie dzięki!
Uwaga:
Ten sam problem istnieje dla C++ 11, gdy jest określony typ zwracany, ale różni w deklaracji szablonu i specjalizacji.
Wygląda na to, że CLang wymaga dopasowania typów zwracanych (funkcji szablonu w deklaracji i specjalizacji klasy szablonów), które nie są częścią podpisu funkcji zgodnie ze standardem. Rozwiązanie "cross-kompilator" określone przez @ max66 ma mieć pustą deklarację klasy szablonu i wymaganych specjalizacji.
z salo r [mcve], możesz uzyskać więcej pomocy. – AndyG
Funkcje specjalistyczne to straszny pomysł. * zawsze * specjalizuj klasy lub funkcje przeciążeniowe w obszarze przestrzeni nazw. – o11c
@ o11c jak widać klasa jest wyspecjalizowana, a nie funkcja, ponieważ częściowa specjalizacja funkcji nie jest dozwolona przez standard. Przeciążenie jest opcją w niektórych przypadkach, ale nie dla kodu o wysokiej wydajności, w którym użycie wirtualnych tabel wpływa na całkowitą szybkość wykonania. – luart