... используется без ошибки параметров шаблона - PullRequest
4 голосов
/ 10 мая 2011

Мне снова нужна ваша помощь ...

У меня был следующий код, который вызывал явную специализацию в области отсутствия пространства имен Ошибка:

namespace __test
{
    template <int A, int B, typename C> class Test
    {
        template <int V> void check(C & a) { }
        template <> void check<0>(C & a) { } //error: explicit specialization in non-namespace scope 'class __test::Test<A, B, C>'
    };
}


Поскольку я уже знаю, как исправить ошибки такого рода, я определил специализацию за пределами области действия класса, однако я получил другую ошибку - ... используется без параметров шаблона :

namespace __test
{
    template <> void Test::check<0>(C & a) { } //error: 'template<int A, int B, class C> class __test::Test' used without template parameters
}


Возможно, я просто глуп, но не понимаю причину этой проблемы и не знаю, как ее исправить ... Пожалуйста, помогите!

Ответы [ 2 ]

4 голосов
/ 10 мая 2011

По моему прочтению стандарта, то, что вы хотите сделать, кажется законным. Цитирование §14.7.3 / 18:

В явном объявлении специализации для члена шаблона класса или шаблона члена, который появляется в области пространства имен, шаблон члена и некоторые из его вмещающих шаблонов классов могут остаться не специализированными, за исключением того, что объявление не должно явно специализироваться шаблон члена класса, если его вложенные шаблоны классов также не являются явно специализированными . В таком явном объявлении специализации должно быть предоставлено ключевое слово template, за которым следует template-parameter-list вместо template<>, предшествующего явному объявлению специализации члена. Типы шаблон-параметров в шаблон-параметров-списка должны совпадать с типами, указанными в определении основного шаблона.

Поскольку вы явно специализируете шаблон функции-члена , а не шаблон члена класса , все должно быть в порядке; однако ни Comeau, ни GCC, ни VC ++ не допускают следующего, который должен быть правильным синтаксисом:

namespace test
{
    template<int A, int B, typename C>
    class Test
    {
        template<int V>
        void check(C& a) { }
    };

    template<int A, int B, typename C>
    template<>
    void Test<A, B, C>::check<0>(C& a) { }
}
  • Comeau говорит error: a template declaration containing a template parameter list may not be followed by an explicit specialization declaration, что имеет смысл, если мы применим правило из §14.7.3 / 18 и к шаблонам функций-членов
  • GCC говорит invalid explicit specialization before '>' token; enclosing class templates are not explicitly specialized, что опять-таки имеет смысл, если мы применим правило в §14.7.3 / 18 также и к шаблонам функций-членов
  • VC ++ говорит error C2768: 'test::Test<A,B,C>::check' : illegal use of explicit template arguments, что не является полезным сообщением об ошибке, но обычно соответствует другим

Моя догадка состоит в том, что должен быть подан отчет о дефекте, который также запрещает явную специализацию шаблонов функций-членов, когда шаблоны классов-оболочек также не являются явно специализированными; однако, я не могу сказать это окончательно, так как формулировка для §14.7.3 / 18 не изменилась между стандартом C ++ 03 и FDIS C ++ 0x (что было бы, если бы DR был подан против C ++ 03 и принято).

3 голосов
/ 10 мая 2011

Вам нужно либо полностью специализировать все, как это:

namespace __test {

template <int A, int B, typename C>
class Test
{
    template <int V> void check(C & a) { }
};

template <>
template <>
void Test<1, 2, int>::check<0> (int &)
{
}

}

Или использовать вспомогательную структуру, чтобы не пытаться частично специализировать шаблонный метод шаблонного класса (который GCC и многие другие не поймут):

namespace __test {

template <typename C, int V>
struct TestHelper
{
    static void check (C & a)
    {
    }
};

template <typename C>
struct TestHelper<C, 0>
{
    static void check (C & a)
    {
    }
};

template <int A, int B, typename C>
class Test
{
    template <int V> void check(C & a)
    {
        TestHelper<C, V>::check (a);
    }
};

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...