类静态成员的冲突声明

时间:2017-07-01 07:08:44

标签: c++ c++11 c++14

#include <iostream>
#include <utility>

using namespace std;

template<typename>
struct Class1;

template<size_t...Is>
struct Class1<index_sequence<Is...>> {
    template<typename T, size_t N>
    struct Holder {
        constexpr Holder(T const(&Ns)[N]) : data{T(Ns[Is] * Is)...} {
        }

        T data[N];
    };
};

template<typename T, T...Ns>
class Class2 {
public:
    static constexpr const size_t N = sizeof...(Ns);
    static constexpr const T mNs[] = {Ns...};
    static constexpr const typename Class1<make_index_sequence<N>>::template Holder<T, N> Hs{mNs}; 
    // If I replace the above N with sizeof...(Ns), the error is gone.
};

template <typename T, T...Ns>
constexpr const typename Class1<make_index_sequence<sizeof...(Ns)>>::template Holder<T, sizeof...(Ns)>
        Class2<T, Ns...>::Hs; // g++ error: conflicting declaration.

int main() {
    cout << &Class2<int, 1, 2, 3>::Hs << endl;
}

这是我的代码的简化版本。它在VS中编译,因为VS不符合这个狗屎。但无法在g ++ 6.3下编译。究竟什么类型的Class2&lt; ...&gt; :: Hs?

基本上我需要在编译时使用另一个数组元素和该元素的索引初始化一个数组。所以,如果有更好的方法,那就更好了。

1 个答案:

答案 0 :(得分:0)

N将保留sizeof...(Ns)的值这一事实似乎具有误导性。我认为此错误是合法的,因为在N声明中使用Hs会使Hs的类型依赖于Class2::N。如果您在Class2< T, Ns... >::N中使用Hs定义错误应该消失:

#include <iostream>
#include <utility>
#include <cstddef>

template< typename > struct
Class1;

template< ::std::size_t...Is > struct
Class1< ::std::index_sequence< Is... > >
{
    template< typename T, ::std::size_t N > struct
    Holder
    {
        constexpr
        Holder(T const(&Ns)[N])
        :   data{T(Ns[Is] * Is)...}
        {}

        T data[N];
    };
};

template< typename T, T...Ns > class
Class2
{
    public: static constexpr const ::std::size_t N{sizeof...(Ns)};
    public: static constexpr const int mNs[]{Ns...};
    public: static constexpr const typename Class1< ::std::make_index_sequence< N > >::
        template Holder< T, N > Hs{mNs};
};

template< typename T, T...Ns >
constexpr const typename Class1< ::std::make_index_sequence< Class2< T, Ns... >::N > >::
    template Holder< T, Class2< T, Ns... >::N > Class2< T, Ns... >::Hs;

int
main()
{
    ::std::cout << &Class2<int, 1, 2, 3>::Hs << ::std::endl;
}

working code online

实际上摆脱N并在任何地方使用sizeof...(Ns)会更短......