0

I have the following function template

template
<
    typename FilterLHS,
    typename FilterRHS,
    typename Of = typename FilterLHS::OfType,
    std::enable_if_t<std::is_base_of_v<Filter<Of>, FilterLHS> && std::is_base_of_v<Filter<Of>, FilterRHS>, int> = 0
>
std::shared_ptr<OrFilter<Of>> operator ||(const std::shared_ptr<FilterLHS> &lhs, const std::shared_ptr<FilterRHS> &rhs)
{
    return std::make_shared<OrFilter<Of>>(OrFilter<Of>{ lhs, rhs });
}

It works fine. My question is, why is the int second argument, and default value of enable_if required? As I understand, especially from this answer, I should just be able to do

template
<
    typename FilterLHS,
    typename FilterRHS,
    typename Of = typename FilterLHS::OfType,
    std::enable_if_t<std::is_base_of_v<Filter<Of>, FilterLHS> && std::is_base_of_v<Filter<Of>, FilterRHS>>
>
std::shared_ptr<OrFilter<Of>> operator ||(const std::shared_ptr<FilterLHS> &lhs, const std::shared_ptr<FilterRHS> &rhs)
{
    return std::make_shared<OrFilter<Of>>(OrFilter<Of>{ lhs, rhs });
}

but when I do that, my template never seems to get enabled.

Adam Rackis
  • 82,527
  • 56
  • 270
  • 393

1 Answers1

2

If the enable_if would go through, the first snippet would produce:

template<int = 0>

Which is valid.

But this, which is what you would get from snippet 2:

template<void>

Isn't and so SFINAE always kicks in here.

Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122
  • Hm - so it seems the linked answer is simply wrong to recommend dropping the default type? – Adam Rackis Aug 04 '19 at 19:08
  • 1
    @AdamRackis I don't think the linked answer is recommending such a thing. There are two different function templates being discussed in that Q&A. The `=0` is required for the one where `enable_if` is used in a template parameter, and the last paragraph in that answer is saying the one where `enable_if` is used in the return type can be written in a shorter way. – aschepler Aug 04 '19 at 19:18
  • 1
    Basically, @AdamRackis, the version without a type parameter is valid in any context where `void` would be valid. In your case, the `enable_if` parameter is a non-type template parameter, and thus cannot be of incomplete type `void`. – Justin Time - Reinstate Monica Aug 04 '19 at 20:39