S в SFINAE означает замену аргументов шаблона для параметров шаблона, что делается для шаблона , когда он рассматривается в качестве кандидата для разрешения перегрузки.
Foo
являетсяшаблон, но set
нет.В результате вы создаете экземпляр Foo
, который создает объявление set
, а функция содержит недопустимый тип возвращаемого значения.Не нужно иметь SFINAE, потому что этот бит замещения не происходит до разрешения перегрузки.
Чтобы применить SFINAE, вы должны сделать set
шаблоном:
template<int NUM = NUM_COMPONENTS>
std::enable_if_t<(NUM== 2), void> set(int64 x, int64 y)
{
// some code here
}
СейчасВы получаете действительное объявление (шаблона).Но когда вы попытаетесь вызвать , произойдет другая замена, к которой применяется SFINAE.
В качестве бонуса, C ++ 20 делает это упражнение спорным.То, чего вы хотите достичь, станет возможным с помощью простого предложения requires
:
void set(int64 x, int64 y) requires (NUM_COMPONENTS == 2)
{
// some code here
}