Clang无法在模板类专门化中编译模板函数,模板类专业化具有来自模板声明的*distinct return type*

lua*_*art 6 c++ template-specialization c++11 clang++ c++14

以下函数derefItemX()在GCC 4.8-5.3上编译正常,但在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);
Run Code Online (Sandbox Code Playgroud)

derefItemX()取消引用值的值或指向该值的指针到原始值的迭代器.CLang显示以下错误消息:说不多:

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)
                                  ^~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释一下:

  1. 为什么CLang无法编译derefItemX()?
  2. 如何使用另一种可以在不同编译器上工作的方法来参数化取消引用*x或**x的迭代器?

非常感谢!

注:
存在指定的返回类型时,C++ 11的同样的问题,但不同的模板声明和专业化.
看起来CLang需要匹配返回类型(模板类声明和特化中的模板函数),这些类型不是根据标准的函数签名的一部分.@ max66指定的"交叉编译器"解决方案是具有模板类的空声明和所需的特化.

max*_*x66 4

我不知道如何以一般方式解决问题;但是这个问题(如果我没记错的话)可以通过专门化整个班级来解决;就像是

#include <iterator>
#include <type_traits>

using namespace std;

template <bool>
struct Operations;

template<>
struct Operations<false> {
   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
       }
};

template<>
struct Operations<true> {
   template<typename IItemXT>
      constexpr 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 value to the value
       }
};
Run Code Online (Sandbox Code Playgroud)

关于“为什么 clang 无法编译”的问题......我很困惑,我不知道 g++ 和 clang++ 之间谁是对的

ps:抱歉我的英语不好