简体   繁体   English

类静态成员的声明冲突

[英]conflicting declaration of class static member

#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;
}

This is the simplified version of my code. 这是我的代码的简化版本。 It compiles in VS because VS does not comformant to this shit. 它在VS中编译,因为VS不符合该要求。 But failed to compile under g++ 6.3. 但是无法在g ++ 6.3下编译。 What exactly is the type of Class2<...>::Hs? Class2 <...> :: Hs的确切类型是什么?

Basically I need to initialize an array using another array's element and the index of that element at compile time. 基本上,我需要在编译时使用另一个数组的元素和该元素的索引来初始化数组。 So if there is a better way, It would be better. 因此,如果有更好的方法,那就更好了。

The fact that N will hold the value of sizeof...(Ns) seems to be misleading. N将保持sizeof...(Ns)的值的事实似乎具有误导性。 I think this error is legit as use of N in Hs declaration makes the type of Hs depend on Class2::N . 我认为,这个错误是合法的使用NHs声明使得类型Hs取决于Class2::N If you use Class2< T, Ns... >::N in Hs definition error should be gone: 如果在Hs定义中使用Class2< T, Ns... >::N应该消失:

#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 在线工作代码

Actually getting rid of N and using sizeof...(Ns) everywhere will be shorter... 实际上摆脱N并在各处使用sizeof...(Ns)会更短...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM