スタックオーバーフローに関する私の多くの質問に対する答えを見つけた後、答えが見つからない質問に出くわしました。誰かが私を助けてくれることを願っています!
私の問題は、C++ のクラス内で関数の明示的なテンプレート化を行いたいということです。私のコンパイラ (g++) と C++ 標準 (§14.7.3) を見ると、この特殊化は、クラスが宣言されている名前空間で行う必要があることがわかります。これは、特殊化をクラス内に置くことができないことを意味することを理解していますが、この制限のポイントがわかりません! クラス内で特殊化を行わせない正当な理由があるかどうか、誰かが知っていますか?
関数を構造体の中に入れるなどの回避策があることは知っていますが、言語がこのような設計になっている理由を理解したいと思います。クラス内で特殊な関数を許可しない正当な理由がある場合は、それを回避する前にそれを知っておく必要があると思います。
前もって感謝します!
私の質問をもう少し正確にするために:これは私がやりたいことを示すテスト例からのいくつかのコードです:
#include <cstdio>
namespace MalinTester {
template <size_t DIMENSIONALITY>
class SpecializationTest {
public:
SpecializationTest() {
privateVariable = 5;
};
virtual ~SpecializationTest() {};
void execute() {
execute<DIMENSIONALITY>();
};
private:
int privateVariable;
template <size_t currentDim>
static void execute() {
printf("This is the general case. Current dim is %d. The private variable is %d.\n", currentDim, privateVariable);
execute<currentDim-1>();
}
template <>
static void execute<0>() {
printf("This is the base case. Current dim is 0.\n");
}
};
これは不可能です; g++ 言います:
SpecializationTest_fcn.h:27: error: explicit specialization in non-namespace scope ‘class MalinTester::SpecializationTest<DIMENSIONALITY>’
SpecializationTest_fcn.h:28: error: template-id ‘execute<0>’ in declaration of primary template
関数 execute をクラス外の名前空間 MalinTester に配置すると、次のようになります。
#include <cstdio>
namespace MalinTester {
template <size_t DIMENSIONALITY> class SpecializationTest {};
template <size_t currentDim>
void execute() {
printf("This is the general case. Current dim is %d. The private variable is %d.\n", currentDim, privateVariable);
execute<currentDim-1>();
}
template <>
void execute<0>() {
printf("This is the base case. Current dim is 0.\n");
}
template <size_t DIMENSIONALITY>
class SpecializationTest {
public:
SpecializationTest() {};
virtual ~SpecializationTest() {};
void execute() {
MalinTester::execute<DIMENSIONALITY>();
};
private:
int privateVariable = 5;
};
};
};
クラス内でプライベートであるため、テンプレート化されたバージョンのexecuteではprivatevariableを使用できません。私は自分のデータを可能な限りカプセル化したいので、それを非公開にしたいと思っています。
もちろん、privateVariable を関数の引数として送信することもできますが、これを回避する方が美しいと思います。C++ 標準が最初の例のように明示的な特殊化を許可しない正当な理由があるかどうかは疑問です。上記のコード例。
@Arne Mertz: これは私が試した回避策ですが、privateVariable の使用も許可されていません。そしてなにより、こうしていいのかなって。メンバー関数の特殊化を行うことは許可されていないため、クラス内の構造体にカプセル化された関数の特殊化も行うべきではないかもしれません。
#include <cstdio>
namespace MalinTester {
template <size_t DIMENSIONALITY>
class SpecializationTest {
public:
SpecializationTest() {
privateVariable = 5;
};
virtual ~SpecializationTest() {};
void execute() {
Loop<DIMENSIONALITY, 0>::execute();
};
private:
int privateVariable;
template <size_t currentDim, size_t DUMMY>
struct Loop {
static void execute() {
printf("This is the general case. Current dim is %d.\n", currentDim);
Loop<currentDim-1, 0>::execute();
}
};
template <size_t DUMMY>
struct Loop<0, DUMMY> {
static void execute() {
printf("This is the base case. Current dim is 0.\n");
}
};
};
};