1
#include <iostream>
#include <array>
using namespace std;

constexpr int N = 10;
constexpr int f(int x) { return x*2; }

typedef array<int, N> A;

template<int... i> struct F { constexpr A f() { return A{{ f(i)... }}; } };

template<class X, class Y> struct C;
template<int... i, int... j>
struct C<F<i...>, F<j...>> : F<i..., (sizeof...(i)+j)...> {};

template<int n> struct S : C<S<n/2>, S<n-n/2>> {}; // <--- HERE
template<> struct S<1> : F<0> {};

constexpr auto X = S<N>::f();

int main()
{
        cout << X[3] << endl;
}

私は得ています:

test.cpp:15:24: error: invalid use of incomplete type ‘struct C<S<5>, S<5> >’

これは、 S の定義がそれ自体を基底クラスとして使用しているためだと思われます。(正しい?)

これを修正する最善の方法は何ですか?

アップデート:

修正版は次のとおりです。

#include <iostream>
#include <array>
using namespace std;

constexpr int N = 10;
constexpr int f(int x) { return x*2; }

typedef array<int, N> A;

template<int... i> struct F { static constexpr A f() { return A{{ ::f(i)... }}; } };

template<class A, class B> struct C {};
template<int... i, int... j> struct C<F<i...>, F<j...>> : F<i..., (sizeof...(i)+j)...>
{
        using T = F<i..., (sizeof...(i)+j)...>;
};

template<int n> struct S : C<typename S<n/2>::T, typename S<n-n/2>::T> {};
template<> struct S<1> : F<0> { using T = F<0>; };

constexpr auto X = S<N>::f();

int main()
{
        cout << X[3] << endl;
}
4

2 に答える 2

2

C単に宣言するのではなく、定義します。

template<class X, class Y> struct C {};

使用する場所では、部分的な特殊化が一致せず、プライマリテンプレートがインスタンス化されます。これは単なる宣言です。

なぜその特殊化が考慮されないのか不思議に思うかもしれません。特殊化は変換を考慮せず、静的型のみを考慮します。それが、彼らが相続と非常に不法に互換性がない理由です。

于 2012-10-27T18:46:09.330 に答える
0

S::f継承を使用する代わりに委任できますか?

template<int n> struct S {
    constexpr A f() { return C<S<n/2>, S<n-n/2>>::f(); }
};
于 2012-10-27T18:54:18.797 に答える