Template-like declaration for function overloads - c++

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

Related

Partially specialize a template on the the first parameter

I tried to do something today that I was surprised to realize didn't work. I have a template that takes a type and a value as parameters. I want to specialize on the type parameter, but leave the value parameter open. Like so
template <class T = void, bool Enabled = false>
struct seFoo {};
template <bool Enabled>
struct seFoo<int, Enabled> {};
// Doesn't work :(
seFoo<false> foo;
However, this leads to a compile error for too few template arguments. It appears the instantiation has to match the signature of the unspecialized template before the compiler will even look at the partial specialization.
Is there a way to get this to work?
If this approach fundamentally isn't possibly, I'm interested in alternative approaches.
Apparently I'm not the only one surprised by this. This article makes the same mistake towards the end.
No, you can't really do this.
Note that a class template partial specialization is not something you can use directly in any way. Its only function is that when you to attempt to use the primary template as normal, if the partial specialization is a match for your template arguments and is the best match among any other explicit / partial specializations, then the partial specialization is used instead of the primary template to generate the definition of that particular class type.
In some cases there are things you can do with default template arguments, defining your own meanings for template arguments, or other such tricks. But there's no way to have one template that can take either a type or a value as its first template argument, and you can't have two class templates or alias templates with the same name in the same scope.

Is a fully specialized template function the same as a regular function?

If I have:
template <typename T>
bool name (std::string);
template <> bool name<int>(std::string);
What is the difference between the fully specialized function and my other regular functions.
For example in the header I would have to have these declarations plus the template definition; nevertheless I can have the specialized definition in a source file along all the other regular functions. Are them the same?
Is that a better practice than having the definition of the specialized template as inline in the header?
A function template specialization determines the effect of a call when the template itself is selected by overload resolution (which uses the signature, but not the definition, of the specialization). This is true whether the specialization is implicitly or explicitly generated.
A separate function participates in overload resolution on its own, competing with the function template at a slight advantage that can easily be offset by template argument deduction (though not here, since your T cannot be deduced). It can be excluded entirely by using an explicit template argument list (even an empty one if all template arguments can be deduced), which means the template should still be given a sensible definition for all types (even if some are deleted or otherwise do not compile).
As for inline, the concerns are no different from those for any function: providing the definition in the header can be important for optimization, allow a header-only library, reduce textual repetition, …or merely produce tighter coupling that makes the code harder to change. Since the definition of the primary template must usually be in the header, there is perhaps a bias toward putting the definition of the specialization there as well. As always, knowledge of the application and judgment is required.

Will we ever get partial specialization of member functions?

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?

C++ template explicit specialization - calling existing member function

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...

Why does the Standard prohibit friend declarations of partial specializations?

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.