DEV Community

Forbid a particular specialization of a template

Pierre Gradot on January 11, 2021

Let's imagine a simple template function that performs basic numerical computations: template <typename T> T f(T t) { return 2 * t + 3...
Collapse
 
atom3333 profile image
Thomas Ferrand

Small typo at the beginning

f(2.3) returns 7.6 and T is int
Should be double.

I also want to point out that the static_assert approach has a major drawback compared to the other ones. It prevents you to accurately detect if your function f is callable with a bool. Indeed with the static_assert you have a function that is defined and takes part in overload resolution and simply produces an error when actually compiled.

I you were using a library that, for some reason, wants to call your function with a bool if supported, else call with an int, the static_assert would fail to compile because the library would think that the function is callable with a bool and attempt to do so before encountering the static_assert. With the other 2 approach, the library would correctly detect that the function cannot be called with a bool and will instead call it with an int.

Granted, this particular situation is unlikely to happen but there is a lot of similar situation in the standard library and in other library where something like that could occur. This is why static_assert is not used much in the standard library but instead SFINAE is used (hopefully replaced by concepts in the future).

Collapse
 
pgradot profile image
Pierre Gradot

Thanks, I have corrected this mistake.

call your function with a bool if supported, else call with an int

I completely understand the principle. But it is not clear to me how would you write such a code. Can you provide a basic example please?

Collapse
 
atom3333 profile image
Thomas Ferrand

Hmm, I wasn't able to implement such detection for a free function because function template don't have a type (only concrete instantiation do).
By wrapping the function inside a struct I can showcase what I was talking about (because now I can make a template that takes my struct as a parameter).
godbolt.org/z/z5a1h6
All in all maybe this is not really a problem with free function but only with member function (static or not).

Collapse
 
sandordargo profile image
Sandor Dargo • Edited

Just a bit of nitpicking. =delete is available also since C++11 according to CppReference

Deleted functions

Regarding concepts, it's worth to note (?) that in case you only want to accept numbers (I'm a bit vague) you have 4 different ways:

#include <concepts>
#include <iostream>

template <typename T>
concept Number = (std::integral<T> || std::floating_point<T>) && (not std::same_as<T, bool>);

template <typename T> 
requires Number<T>
T f(T t) {
    return 2 * t + 3;
}

template <typename T> 
auto f2(T t) requires Number<T> {
    return 2 * t + 3;
}

template <Number T>
auto f3(T t) {
    return 2 * t + 3;
}

auto f4(Number auto t) {
    return 2 * t + 3;
}

int main () {
    std::cout << f(2) << std::endl;
    std::cout << f2(2.2) << std::endl;
    std::cout << f3(3) << std::endl;
    std::cout << f4(-2.4) << std::endl;
    // std::cout << f2(true) << std::endl; // auto f2(T) requires  Number<T> [with T = bool]' with unsatisfied constraints
}
Enter fullscreen mode Exit fullscreen mode

I'll write a more detailed post about the 4 ways of concepts.

_Please note that the concept Number is incomplete, it accepts char for example _

Collapse
 
pgradot profile image
Pierre Gradot • Edited

This is not being "nitpicking": this is being "accurate". Thanks! I fixed that.

In fact, I missed this warning:

warning: deleted function definitions are a C++11 extension [-Wc++11-extensions]

I have not really dived into concepts yet, so I am really interested by your future article!

PS: I have added a PS to my article above ; )

Collapse
 
sandordargo profile image
Sandor Dargo

Gosh, I started that article, and it's already longer than the whole series on constness. I'll have to break it down :)

Thread Thread
 
pgradot profile image
Pierre Gradot

Not surprising XD

Collapse
 
sandordargo profile image
Sandor Dargo

Thanks a lot for the PS :)

I have to start writing that article soon!