声明对另一个 class 的模板化成员数组的模板化成员引用
Declaring templated member reference to templated member array of another class
模板 class OtherClass
有一个模板成员,它是对模板 class BitReferenceHost
模板成员的引用,它是一个 std::array
使用 make_integer_sequence
和两个模板化成员构建的BitReferenceHost
的方法。
我在 BitReferenceHost
中正确声明了 XBitMask
,但我在 OtherClass
中遇到了问题,它使用了对 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)删除class定义外的声明
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;
模板 class OtherClass
有一个模板成员,它是对模板 class BitReferenceHost
模板成员的引用,它是一个 std::array
使用 make_integer_sequence
和两个模板化成员构建的BitReferenceHost
的方法。
我在 BitReferenceHost
中正确声明了 XBitMask
,但我在 OtherClass
中遇到了问题,它使用了对 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)删除class定义外的声明
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;