In C++11 it is not possible to partially specialize member functions independent of the containing class, as noted here: c++ template partial specialization member function
My question: is this likely to change? Are there proposals in the pipeline to fix this shortcoming?
Related
Here it says that the inability to partially specialize function templates directly is essentially an oversight or a defect.
If that's really the case - why wasn't this fixed in C++14? And more importantly - when will it be fixed? Is it expected for C++17 to allow for partial function template specialization?
I'm using explicit template specialization to initialize a std::vector with information but only for a specific type of std::vector, thus the explicit specialization. Within the constructor, if I try to call push_back or any other existing function in std::vector, compilation fails. What is the problem and how do I fix it?
simplified example:
namespace std
{
template<>
class vector<int>
{
public:
vector(void)
{
int value = 5;
push_back(value);
}
};
}
compiler message:
In constructor 'std::vector<int>::vector()':
error: 'push_back' was not declared in this scope
push_back(value);
^
Explicit specializations are completely different classes that are separate from the primary template. You have to rewrite everything.
In normal situations where you control the primary template, you would typically have some sort of common base class or base class template to collect common structures.
With a given library, it is generally a very bad idea to add specializations (unless the library explicitly says it's OK). With the C++ standard library, this is outright undefined behaviour.
(The main problem is that other translation units may be using the template instantiation which you're specializing without seeing your specialization, which violates the one-definition rule.)
Template specializations are unrelated types from both the primary template and any other specialization. It is unclear what you are attempting to do, as it is also illegal to provide specializations of templates in the std namespace unless the specialization uses your own user defined type.
If you can explain the problem to solve, you might get other options, like specializing a member function rather than the template itself...
The C++ standard prohibits friend declarations of partial specializations. (ยง14.5.3/8):
Friend declarations shall not declare partial specializations. [Example:
template<class T> class A { };
class X {
template <class T> friend class A<T*>; //error
};
--end example]
Other questions, e.g. this one,
have received answers that invoke this prohibition, but I would like to know the
rationale. I don't see it and can't find it with my favourite search engine. I
can find however that it goes right back to the C++98 standard, so presumably
the rationale is quite basic and clear. Can someone explain it to me?
I don't have a reference but I suspect that this is because it would result in the partial specialization being declared in the scope of the friend-declaring class rather than the scope of the template in question, and rather than creating a bunch of rules to force the friend declaration to result in the specialization being in the correct scope, they simply prohibit it.
Here is some undirect explanation:
http://www.cprogramming.com/tutorial/template_specialization.html
A final implementation detail comes up with partial specializations:
how does the compiler pick which specialization to use if there are a
combination of completely generic types, some partial specializations,
and maybe even some full specializations? The general rule of thumb is
that the compiler will pick the most specific template
specialization--the most specific template specialization is the one
whose template arguments would be accepted by the other template
declarations, but which would not accept all possible arguments that
other templates with the same name would accept.
I infer that maybe it is not permitted to prevent any ambiguity in the determination of specialization type.
The Wikipedia article says this:
instantiating a class template does not cause its member definitions to be instantiated.
I can't imagine any class in C++ being instantiated, whether from a template or not, where that classes members were not also instantiated?
Many early C++ compilers instantiated all member functions, whether you ever called them or not.
Consider, for example, std::list, which has a sort member function. With a current, properly functioning compiler, you can instantiate list over a type that doesn't support comparison. If you try to use list::sort, it will fail, because you don't support comparison. As long as you don't call sort for that list, it's all fine though, because list<T>::sort won't be instantiated unless you call it.
With those older, poorly functioning compilers, however, trying to create list<T> meant that list<T>::sort was instantiated even though you never used it. The existence of list::sort meant that you needed to implement < for T, just to create a list<T>, even if you never actually used sort on a list of that type at all.
The standard clearly says that (both non-template and template) member methods instantiation should happen only when used.
An excerpt from C++ standard (N3690 - 14.7.1(2) Implicit instantiation)
2 Unless a member of a class template or a member template has been explicitly instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist; in particular, the initialization (and any associated side-effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist.
Methods of a class are also members. Class Template methods are instantiated when they are called for that instantiated class. So it is possible that those member methods are never instantiated.
Can I make generic function declarations at the start of my header file?
I can do template<class t> t func(t); then specialize it, but
Template Specialization VS Function Overloading
says not to do that.
First, you can surely declare a template function and then define it, and/or define specializations. But...
Function specializations must be full specializations, that is, you cannot partially specialize a template function. Now, while you can actually specialize the function template, providing overload may have advantages (and disadvantages), but in most cases it will be a better option.
You might want to read this: http://www.gotw.ca/publications/mill17.htm