Domanda

I am still trying to figure out templates. I have read about the specialization rules and don't understand what is happening here.

I have defined the following in templates.h:

#include <iostream>

template <typename foo>
void f(foo p)
{
  std::cout << "one" << std::endl;
}

template <typename bar>
void f(int p)
{
  std::cout << "two" << std::endl;
}

Now if I include this and call it in my main like this

  f(1);
  f("x");

I get

one
one

Now the questions is, why is the first more specific than the second for ints? I feel like it should at least be ambiguous and not work at all.

È stato utile?

Soluzione

The second overload one has no template dependency on function arguments, so you would have to call it like this:

f<std::string>(1);
f<double>(42);
f<SomeType>(1);

Whether it makes sense to have the second version is a different matter. You could imagine having a template parameter that does have some effect on the internal logic of the function:

template <typename SomeType>
int foo(int seed) {
  // instantiate a SomeType and use it to calculate return value
};

int i = foo<Type1>(42);
int j = foo<Type2>(42);

On the other hand, your SomeType could be a function parameter:

template <typename SomeType>
int foo(int seed, const SomeType& s) {
  // use s to calculate return value
};

Type1 t1;
Type2 t2;
int i = foo(42, t1);
int j = foo(42, t2);

Altri suggerimenti

First off, you don't have specializations, but two separate, unrelated overloads.

Secondly, the second overload is trivially non-viable, since you call the function without template arguments, and thus there is no way to deduce the template parameter bar. So only the first overload is viable, and gets used.


An actual specialization would look like this:

template <>
void f<int>(int p) { /* ... */ }

Better yet, stick with overloads (it's generally better to overload functions than to provide template specializations), but make the second one a non-template:

void f(int p) { /* ... */ }

In the second one bar cannot be deduced from function arguments, and must be given explicitly:

f<whatever>(1);

The one, which prints "two" is not recognized as explicit specialization. Try thisL

template <>
void f(int p)
{
  std::cout << "two" << std::endl;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top