Why can't you partially specialize a class member function?

て烟熏妆下的殇ゞ 提交于 2021-01-29 05:03:36

问题


Member functions of template classes can be fully specialized, e.g.

template<class A>
struct MyClass {
    // Lots of other members
    int foo();
};

template<class A>
MyClass<A>::foo() { return 42; }

template<>
MyClass<int>::foo() { return 0; }

would compile without problems. Note that foo() is not a template function so this is not about template function specialization (I can understand partial specialization is not allowed there as it would become incredibly confusing in combination with overloading). In my opinion, the above code is just a shorthand for the following template class specialization:

template<class A>
struct MyClass {
    // Lots of other members
    int foo();
};

template<class A>
MyClass<A>::foo() { return 42; }

template<>
struct MyClass<int> {
    // Copy all the other members from MyClass<A>
    int foo();
};

template<>
MyClass<int>::foo() { return 0; }

Is this correct?

In this case I'm wondering why a partial specialization with a similar shorthand is not allowed, i.e. why can I not write

template<class A, class B>
struct MyClass {
    // Lots of other members
    int foo();
};

template<class A, class B>
MyClass<A,B>::foo() { return 42; }

template<class B>
MyClass<int,B>::foo() { return 0; }

as a shorthand for

template<class A, class B>
struct MyClass {
    // Lots of other members
    int foo();
};

template<class A, class B>
MyClass<A,B>::foo() { return 42; }

template<class B>
struct MyClass<int,B> {
    // Copy all the other members from MyClass<A,B>
    int foo();
};

template<class B>
MyClass<int,B>::foo() { return 0; }

Since the 2nd fragment is legal and the 1st one would be completely equivalent to it (but without me having to explicitly copy all the other data members and maintain them in parallel forever), I don't see why the 1st one is not allowed.

I am aware that this question has already been asked here and here, but I am not looking for an answer of the type "Indeed it is not allowed." or "It is not allowed because the standard says it isn't.", nor for ways to circumvent this problem. I am wondering why the standard does not allow it, i.e. is there a fundamental reason for this or could it be allowed in the future? I didn't find this in any of the apparent duplicate questions so far.


回答1:


The answer to your first question -- whether the second fragment is indeed equivalent to the first -- is "no".

In particular, your comment "// Copy all the other members from MyClass" doesn't really work: Those members have to remain members of a class template to ensure that they're only "instantiated on-demand". Otherwise, you're likely to get spurious early errors on members you never actually used.

(There is also an unfortunate issue that in C++ not all implicit instantiations can be written as an equivalent explicit specialization.)

That doesn't mean we couldn't come up with a specification to add similar functionality. It's just more subtle than "do the same as with full specialization", and so far I'm not aware of a serious effort to bring this to the standard.



来源:https://stackoverflow.com/questions/32397948/why-cant-you-partially-specialize-a-class-member-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!