Stack Overflow Asked by Reizo on October 11, 2020
I was wondering about the advantage of std::enable_if
over static_asserts
to prevent template instantiation. This answer suggests, that std::enable_if
allows SFINAE, which is a convincing argument in the case of function templates.
However is this argument legitimate for class templates (and variable templates)? As far as I know, there is no overload resolution involved there, making SFINAE – again, as far as I know – not relevant, but I might be wrong. If so, can you name an example?
If not, I assume static_assert
to be the better solution for the given issue (preventing template instantiation) in the case of class templates, since it’s arguably more explicit, concise and readable and allows a custom error message. Is that correct or am I missing a point other than SFINAE?
Example of how to overload classes using SFINAE:
#include <type_traits>
#include <iostream>
template <typename, typename = void>
struct Foo;
template <typename Bar>
struct Foo <Bar, typename std::enable_if<std::is_same<Bar,int>::value>::type>
{
Foo ()
{
std::cout << "Hello ";
}
};
template <typename Bar>
struct Foo <Bar, typename std::enable_if<std::is_same<Bar,bool>::value>::type>
{
Foo ()
{
std::cout << "world!n";
}
};
int main()
{
Foo<int>();
Foo<bool>();
}
For cases where you don't want to do overloading but still want to restrict to a set of types, I agree that:
template <typename Bar>
class Foo
{
static_assert(
std::is_same<Bar,int>::value ||
std::is_same<Bar,bool>::value,
"Bar must be bool or int");
// class stuff
};
...is clearer and simpler than:
template <typename Bar,
typename std::enable_if<
std::is_same<Bar,int>::value ||
std::is_same<Bar,bool>::value,
bool>::type = true>
class Foo
{
// class stuff
};
...especially because with the second option the compiler refers to Foo
objects with their first argument and their second argument (true
, in our case), which can be mysterious to the user. Also, it's more messy if you want a header to handle the class with only a light-weight declaration of it (see how to do that here).
Correct answer by Elliott on October 11, 2020
std::enabled_if is used in SFIANE for specialization of template classes, methods and .... static_assert is used for checking a contract at compile time, and providing a useful error message.
Answered by apramc on October 11, 2020
However is this argument legitimate for class templates (and variable templates)? As far as I know, there is no overload resolution involved there, making SFINAE - again, as far as I know - not relevant, but I might be wrong. If so, can you name an example?
You can specialise class templates and SFINAE may be used to pick between specialisations. It will also prevent instantiation of such (by then, possibly ill-formed) class / its specialisation, instead of failing to compile due to static_assert
.
Answered by Fureeish on October 11, 2020
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP