2016-12-22 6 views
3

Шаблона class OtherClass имеет элемент шаблона, который является ссылкой на шаблон class BitReferenceHost элемента «ы шаблон, который является std::array построен с использованием make_integer_sequence и два шаблонных методов членов BitReferenceHost.Объявление шаблонных контрольного элемента массива для шаблонного члена другого класса

я правильно объявил XBitMask в BitReferenceHost, но у меня возникли проблемы в 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; 

Update (Solution):

Рабочий код в ответ, предоставленный 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; 
} 

ответ

1

Я не эксперт, но ... У меня есть проблемы с компиляцией кода, потому что (если Я понимаю, а сообщение об ошибке с лязгом) в 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 для типа (и usign в using определенного типа к semplify)

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; 
+0

Все примеры, которые я нашел для # 2, приводят к clang и gcc segfaulting - http://melpon.org/wandbox/permlink/YwxOasovCcbkqGjL – Asher

+0

И # 1 означает, что он недоступен вне класса. – Asher

+0

@Asher - извините, но проблема «она недоступна вне класса» связана с тем, что 'XBitMask' определен' private' (defaul в классе) в 'OtherClass' и в' BitReferenceHost'; попробуйте определить их как «публичные». – max66

Смежные вопросы