Nachdem ich Antworten auf viele meiner Fragen zu stackoverflow gefunden habe, bin ich nun auf eine Frage gestoßen, auf die ich keine Antwort finden kann und ich hoffe, dass mir jemand hilft!Warum sind Funktionsvorlagenspezialisierungen in einer Klasse nicht zulässig?
Mein Problem ist, dass ich eine explizite Templatisierung einer Funktion innerhalb einer Klasse in C++ machen möchte. Mein Compiler (g ++) und ein Blick in den C++ - Standard (§14.7.3) sagen mir, dass diese Spezialisierung in dem Namensraum erfolgen muss, in dem die Klasse deklariert ist. Ich verstehe, dass dies bedeutet, dass ich die Spezialisierung nicht innerhalb der Klasse platzieren kann, aber ich sehe den Sinn dieser Einschränkung nicht! Weiß jemand, ob es einen guten Grund gibt, die Spezialisierungen nicht in der Klasse machen zu lassen?
Ich weiß, dass es Problemumgehungen gibt, z. um die Funktion in eine Struktur einzufügen, aber ich möchte verstehen, warum die Sprache dieses Design hat. Wenn es einen guten Grund dafür gibt, spezialisierte Funktionen in der Klasse nicht zuzulassen, sollte ich es vermutlich wissen, bevor ich versuche, es zu umgehen.
Vielen Dank im Voraus!
Auf meine Frage ein wenig präzisieren: Hier ist ein Code aus einem Testbeispiel, das, was veranschaulicht die ich tun möchte:
#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");
}
};
ist dies nicht möglich; g ++ sagt:
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
Wenn ich die Funktion ausführen außerhalb der Klasse setzen, im Namensraum MalinTester, wird es wie folgt aussehen:
#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;
};
};
};
und ich kann in den templatized Versionen ausführen nicht privatevariable verwenden , wie es privat in der Klasse ist. Ich wirklich will es privat, wie ich meine Daten so weit wie möglich eingekapselt haben möchte.
Natürlich kann ich privateVariable als Argument für die Funktion senden, aber ich denke, es wäre schöner, dies zu vermeiden, und was ich wirklich frage ist, wenn es einen guten Grund für den C++ - Standard keine explizite Spezialisierung zu erlauben wie im ersten Codebeispiel oben.
@Arne Mertz: Dies ist die Abhilfe, die ich versucht habe, aber es darf nicht privateVariable entweder verwenden. Und vor allem frage ich mich, ob es eine gute Idee ist, so zu handeln. Da es mir nicht erlaubt ist, Spezialisierungen von Member-Funktionen vorzunehmen, sollte ich vielleicht auch keine Spezialisierungen von Funktionen machen, die in Strukturen innerhalb der Klasse gekapselt sind.
#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");
}
};
};
};
Relevant, denke ich. http://stackoverflow.com/questions/18294990/why-can-templatet-but-not-template-be-defined-outside-of-a-namespace-block/ – Rapptz
Welches genaue Problem gibt es um zu arbeiten? Können Sie nicht einfach die Spezialisierung in den Namensraum setzen? –
n.m .: Ich möchte die Instanzvariablen der Klasse in den Funktionen verwenden. Wenn ich die Spezialisierung außerhalb der Klasse in den Namespace lege, hat die Funktion keinen Zugriff darauf (es sei denn, ich sende eine Instanz der eigentlichen Klasse als Argument an die Funktion, aber das macht den Code meiner Meinung nach hässlicher.) – Malin