lundi 27 juin 2016

CLang fails to compile template function with auto return type inside a template class

The following function derefItemX() is compiled fine on GCC 4.8-9, but fails on CLang 3.8:

//! 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() dereferences an iterator of either a value or a pointer to the value to original value. CLang shows the following error message: that says not much:

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)
                                  ^~~~~~~~~~

Can anybody please explain:

  1. Why does CLang fail to compile derefItemX()?
  2. How to parameterize an iterator dereferencing to either *x or **x using another approach that would work on different compilers?

Thanks a lot!

Aucun commentaire:

Enregistrer un commentaire