c++ - 声明对另一个类的模板化成员数组的模板化成员引用

标签 c++ templates c++14 variadic-templates static-variables

模板 class OtherClass 有一个模板成员,它是对模板 class BitReferenceHost 模板成员的引用,它是一个 std::array 使用 make_integer_sequenceBitReferenceHost 的两个模板化成员方法构建。

我已经在 BitReferenceHost 中正确声明了 XBitMask,但是我在 OtherClass 中遇到了问题,它使用了对 的静态成员的引用code>BitReferenceHost.

#include <cstdint>
#include <array>
#include <limits>
#include <functional>

template <typename Aspect>
class BitReferenceHost {
    public:

    template <uint8_t BitCount, uint64_t... Indexes>
    static constexpr const std::array<uint64_t, sizeof...(Indexes)>
    initializeXBitMasks(const std::integer_sequence<uint64_t, Indexes...>&) {
        return { initializeXBitMasks<BitCount>( Indexes )... };
    }

    template<
        uint8_t   BitCount,
        uint8_t   ShiftDistance = BitCount + 1,
        uint64_t  BaseMask      = (1ULL << ShiftDistance) - 1
    > static constexpr const uint64_t initializeXBitMasks(
        const uint64_t& mask_index
    ) {
        return BaseMask << (BitCount * mask_index);
    }

    template <
        uint8_t   BitCount,
        typename  MaskInt = uint64_t,
        uint8_t   Count   = std::numeric_limits<MaskInt>::digits / BitCount
    > static constexpr const std::array <MaskInt, Count>
    XBitMask = initializeXBitMasks<BitCount>(
        std::make_integer_sequence<MaskInt, Count>{}
    );

};

template <typename Aspect>
template <uint8_t  BitCount,
  typename MaskInt,
  uint8_t  Count
> const std::array<MaskInt, Count> BitReferenceHost<Aspect>::XBitMask;

template <typename Aspect, typename... Args>
class OtherClass {
    public:
    using ReferenceHost = ::BitReferenceHost<Aspect>;

    template <uint8_t  BitMaskBitCount>
    static constexpr const auto& XBitMask =
            ReferenceHost::template XBitMask<BitMaskBitCount>;
};

template <typename Aspect, typename... Args>
template <uint8_t  BitMaskBitCount>
const auto& OtherClass<Aspect, Args...>::XBitMask;

更新(解决方案):

max66 提供的每个答案的工作代码:

#include <cstdint>
#include <iostream>
#include <array>
#include <limits>
#include <functional>

template <typename  Aspect> class BitReferenceHost {
  template <uint8_t BitCount, uint64_t... Indexes>
  static constexpr const std::array<uint64_t, sizeof...(Indexes)>
  initializeXBitMasks( const std::integer_sequence<uint64_t, Indexes...>& )
  {
    return { { initializeXBitMasks<BitCount>( Indexes )... } };
  }
  template
  <
    uint8_t   BitCount,
    uint64_t  BaseMask      = (1ULL << BitCount) - 1
  >
  static constexpr uint64_t
  initializeXBitMasks(
    const uint64_t&  mask_index )
  {
    return BaseMask << (BitCount * mask_index);
  }

   public:
  template
  <
    uint8_t   BitCount,
    typename  MaskInt = uint64_t,
    uint8_t   Count   = std::numeric_limits<MaskInt>::digits / BitCount
  >
  static constexpr const std::array<MaskInt,Count>
  XBitMask = initializeXBitMasks<BitCount>( std::make_integer_sequence<MaskInt, Count>{} );
};

template<typename  Aspect>
template
<uint8_t BitCount, typename MaskInt, uint8_t Count>
const std::array<MaskInt, Count>
BitReferenceHost<Aspect>::XBitMask;

template <typename Aspect, typename... Args> class OtherClass
{
  using ReferenceHost = ::BitReferenceHost<Aspect>;
   public:
  template <uint8_t  BitMaskBitCount> static constexpr const decltype(ReferenceHost::template XBitMask<BitMaskBitCount>)&
  XBitMask = ReferenceHost::template XBitMask<BitMaskBitCount>;
};

template <typename Aspect, typename... Args>
template <uint8_t  BitMaskBitCount>
constexpr const decltype(OtherClass<Aspect, Args...>::ReferenceHost::template XBitMask<BitMaskBitCount>)&
OtherClass
<Aspect, Args...>::XBitMask;

int main()
{
  uint64_t test_int = OtherClass<uint64_t>::XBitMask<1>[0];

  std::cout << test_int << std::endl;

  return 0;
}

最佳答案

我不是专家,但是...我在编译您的代码时遇到问题,因为(如果我很好地理解来自 clang 的错误消息)auto 输入

template <typename Aspect, typename... Args>
template <uint8_t  BitMaskBitCount>
const auto& OtherClass<Aspect, Args...>::XBitMask;

无法推导,因为没有初始化值。

我用两种方式编译

(1)删除类定义外的声明

template <typename Aspect, typename... Args>
class OtherClass {
    using ReferenceHost = ::BitReferenceHost<Aspect>;

    template <uint8_t  BitMaskBitCount>
    static constexpr const auto& XBitMask =
            ReferenceHost::template XBitMask<BitMaskBitCount>;
};

//template <typename Aspect, typename... Args>
//template <uint8_t  BitMaskBitCount>
//const auto& OtherClass<Aspect, Args...>::XBitMask;

(2) 避免使用 auto 类型(并使用 using 定义的类型来简化)

template <typename Aspect, typename... Args>
class OtherClass {
    using ReferenceHost = ::BitReferenceHost<Aspect>;
    template <uint8_t  BitMaskBitCount>
    using xbit_t        = decltype(ReferenceHost::template XBitMask<BitMaskBitCount>); 

    template <uint8_t  BitMaskBitCount>
    static constexpr xbit_t<BitMaskBitCount> & XBitMask =
            ReferenceHost::template XBitMask<BitMaskBitCount>;
};

template <typename Aspect, typename... Args>
template <uint8_t  BitMaskBitCount>
constexpr OtherClass<Aspect, Args...>::xbit_t<BitMaskBitCount> & 
   OtherClass<Aspect, Args...>::XBitMask;

关于c++ - 声明对另一个类的模板化成员数组的模板化成员引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41274174/

相关文章:

c++ - 如何在 C++ 中将整数连接到对象名称的末尾

c++ - 模板类中函数指针的成员给出错误 : must be a class or namespace when followed by '::'

c++ - 模板组合和友元传递性

c++ - 从 constexpr 函数返回一个类需要使用 g++ 的 virtual 关键字

c++ - 具有前向声明类型的函数模板特化

c++ - 在重载解析期间调用转换运算符而不是转换 C++17 中的构造函数

c++ - std::shared_ptr::reset() "invalidates"其他引用

c++ - 在包围点的网格内找到三角形的快速方法

c++ - enable_if 添加具有默认参数的函数参数?

javascript - 如何通过javascript从模板中获取元素?