I have a question about what is proper/correct way to use templates in C++.
Let's say we have a template class like this:
template <typename T> class Foo
{
public:
T add(T n1, T n2);
};
template <typename T> T Foo<T>::add(T n1, T n2)
{
return(n1 + n2);
}
This will work very good with basic datatypes, like int, double, float, char ...etc.
Foo <int> foo_int;
std::cout << std::to_string(foo_int.add(2, 5)) << std::endl;
Foo <double> foo_double;
std::cout << std::to_string(foo_double.add(2.2, 6.1)) << std::endl;
Foo <char> foo_char;
std::cout << std::to_string(foo_char.add('A', 'm')) << std::endl;
But this will not work very well with complex datatypes, like this one:
class Bar
{
public:
std::string bar;
};
Bar bar_1;
Bar bar_2;
Foo <Bar> foo_bar;
std::cout << std::to_string(foo_int.add(bar_1, bar_2)) << std::endl;
Is it OK to write templates that only works with a handful datatypes, or should templates only be used in case where it works with all kind of datatypes, like std::vector.
In case, if it's proper to write templates that only works for a handful of datatypes, how should it be written? In case of class Foo
, I will know that Foo
only works with basic datatypes, but let say I give the code of Foo
to Alice, she doesn't know that. So she will get a compiler error if she uses Foo
with complex datatypes.
Is there away to tell compiler/prorammer that the templates only works with certain datatypes, except the errors the compiler will throw.
But this will not work very well with complex datatypes, like this one:
That's because Bar
does not provide Bar::operator+(Bar, Bar)
- if it did, it would work with your template.
Is it OK to write templates that only works with a handful datatypes
Depending on your use case, yes. You usually want to support all datatypes that conform to a particular concept, but sometimes you might also want to support a fixed set of types.
Is there away to tell compiler/prorammer that the templates only works with certain datatypes, except the errors the compiler will throw.
If you want your template to work with all types that conform to a particular interface, you want to use concepts (available in C++20, can be emulated in C++11).
You can check properties about types with the detection idiom and use static_assert
(or SFINAE) to provide compile-time errors for users of your class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With