Warum sind Spezialisierungen von Funktionsschablonen in einer Klasse nicht zulässig?

Nachdem ich Antworten auf viele meiner Fragen zum Stackoverflow gefunden habe, bin ich jetzt auf eine Frage gestoßen, deren Antwort ich nicht finden kann, und ich hoffe, dass jemand bereit ist, mir zu helfen!

Mein Problem ist, dass ich eine explizite Vorlage für eine Funktion in einer Klasse in C ++ erstellen möchte. Mein Compiler (g ++) und ein Blick in den C ++ - Standard (§14.7.3) zeigen mir, dass diese Spezialisierung in dem Namespace erfolgen muss, in dem die Klasse deklariert ist. Ich verstehe, dass dies impliziert, dass ich die Spezialisierung nicht in die Klasse einordnen kann, aber ich verstehe den Sinn dieser Einschränkung nicht! Weiß jemand, ob es einen guten Grund gibt, die Spezialisierungen nicht innerhalb der Klasse vornehmen zu lassen?

Ich weiß, dass es Problemumgehungen gibt, z. um die Funktion innerhalb einer Struktur zu platzieren, aber ich möchte verstehen, warum die Sprache dieses Design hat. Wenn es einen guten Grund gibt, spezielle Funktionen in der Klasse nicht zuzulassen, sollte ich das wissen, bevor ich versuche, es zu umgehen.

Danke im Voraus!

Um meine Frage etwas präziser zu gestalten: Hier ist ein Code aus einem Testbeispiel, der zeigt, was 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");
    }

};

Das ist 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 execute außerhalb der Klasse im Namensraum MalinTester platziere, sieht das so aus:

#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 privatevariable in den Vorlagenversionen von execute nicht verwenden, da es in der Klasse privat ist. Ich [...] wirklichwollen Es ist privat, da ich meine Daten so weit wie möglich kapseln lassen möchte.

Natürlich kann ich privateVariable als Argument an die Funktion senden, aber ich denke, es wäre schöner, dies zu vermeiden, und ich frage mich wirklich, ob es einen guten Grund dafür gibt, dass der C ++ - Standard keine explizite Spezialisierung wie in der ersten zulässt Codebeispiel oben.

@Arne Mertz: Dies ist die Problemumgehung, die ich versucht habe, aber es erlaubt auch nicht, privateVariable zu verwenden. Und vor allem frage ich mich, ob es eine gute Idee ist, dies zu tun. Da ich keine Spezialisierungen von Member-Funktionen vornehmen darf, sollte ich vielleicht auch keine Spezialisierungen von Funktionen vornehmen, die in Strukturen innerhalb der Klasse eingekapselt 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");
        }
    };
};
};

Antworten auf die Frage(1)

Ihre Antwort auf die Frage