Reputation: 15284
I have this code to determine if the template type has foo():
template <typename T, typename = void>
struct has_foo : std::false_type {};
template <typename T>
struct has_foo<T, std::void_t<decltype(std::declval<T&>().foo()) > > : std::true_type {};
template <typename T>
void has_foo_f(){
static_assert(has_foo<T>::value, "Type does not have foo().");
}
Then I have the bar
function that takes a template parameter with foo
:
template<typename T, typename = decltype(has_foo_f<T>())>
void bar(){}
In the main file, I have a fail case:
//Foo does not implement foo(). It should fail!
template<typename T>
class Foo{};
int main()
{
has_foo_f<Foo<int>>(); //This line fail
bar<Foo<int>>(); //This line does not fail
}
When I call has_foo_f
directly, the compiler gives me static assertion error, which is correct.
However when I call bar<Foo<int>>
, the compiler successfully compiled it without error.
Why does this happen? Why is the static_assert not evaluated? I understand decltype
does not need to evaluate static_assert
to get the type info, but isn't static_assert
always evaluated at compile time?
Upvotes: 0
Views: 119
Reputation: 37468
Operand of decltype
is not evaluated and therefore does not require function definition to exist (or return type being complete) while function template is instantiated when the specialization is referenced in a context that requires a function definition to exist. So you need to instantiate function template for check inside of function body to take place:
template<typename T, auto Dummy = &has_foo_f<T>>
void bar(){}
Upvotes: 2