开发者

... used without template parameters error

开发者 https://www.devze.com 2023-03-05 07:19 出处:网络
I am in need of your help once again... I had the following code, which was causing exp开发者_如何学Clicit specialization in non-namespace scope error:

I am in need of your help once again...

I had the following code, which was causing exp开发者_如何学Clicit specialization in non-namespace scope error:

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>'
    };
}

Since I already know how to fix this kind of errors, I defined specialization outside of the class scope, however I got another error - ... used without template parameters:

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

I'm probably just being stupid, but I don't understand the cause of this problem and I don't know how to fix it... Please help!


By my reading of the standard, what you want to do appears to be legal. Quoting §14.7.3/18:

In an explicit specialization declaration for a member of a class template or a member template that appears in namespace scope, the member template and some of its enclosing class templates may remain unspecialized, except that the declaration shall not explicitly specialize a class member template if its enclosing class templates are not explicitly specialized as well. In such explicit specialization declaration, the keyword template followed by a template-parameter-list shall be provided instead of the template<> preceding the explicit specialization declaration of the member. The types of the template-parameters in the template-parameter-list shall be the same as those specified in the primary template definition.

As you're explicitly specializing a member function template rather than a class member template, it should be fine; however, neither Comeau, GCC, nor VC++ allow the following, which should be correct syntax:

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 says error: a template declaration containing a template parameter list may not be followed by an explicit specialization declaration, which makes sense if we apply the rule in §14.7.3/18 to member function templates as well
  • GCC says invalid explicit specialization before '>' token; enclosing class templates are not explicitly specialized, which again makes sense if we apply the rule in §14.7.3/18 to member function templates as well
  • VC++ says error C2768: 'test::Test<A,B,C>::check' : illegal use of explicit template arguments, which isn't a helpful error message, but generally falls in line with the others

My guess is that there must be a defect report filed that also disallows explicit specializations of member function templates when the enclosing class templates are not explicitly specialized as well; however, I can't say this definitively since the wording for §14.7.3/18 hasn't changed between the C++03 standard and the C++0x FDIS (which it would if a DR was filed against C++03 and accepted).


You need to either fully specialize everything, like this:

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 &)
{
}

}

Or use a helper structure to avoid trying to partially specialize template method of a template class (which GCC and many others won't understand):

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);
    }
};

}
0

精彩评论

暂无评论...
验证码 换一张
取 消