SFINAE允许吗?

Aar*_*ing 2 c++ template-meta-programming

我正在尝试使用std :: enable_if从类模板中删除成员函数。当我禁用一个功能时,我得到了错误:

C2938: 'std::enable_if_t<false,int64_t>' : Failed to specialize alias template
Run Code Online (Sandbox Code Playgroud)

我的代码如下所示:

template<int NUM_COMPONENTS>
struct Foo
{
    typename std::enable_if_t<(NUM_COMPONENTS == 2), void> set(int64 x, int64 y)
    {
        // some code here
    }
}
Run Code Online (Sandbox Code Playgroud)

我是否正在执行该标准不允许的操作,如果可以的话,还有另一种方法吗?还是这是一个错误?我正在将MSVC与QtCreator一起使用。

Sto*_*ica 5

在SFINAE S代表的模板参数模板参数取代为一个做模板时,它视为重载的候选人。

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
}
Run Code Online (Sandbox Code Playgroud)

现在,您将获得有效的(模板)声明。但是,当您尝试调用它时,将会发生另一种替换,适用SFINAE。

作为奖励,C ++ 20使此练习无济于事。一个简单的requires子句可以实现您想要实现的目标:

void set(int64 x, int64 y) requires (NUM_COMPONENTS == 2)
{
    // some code here
}
Run Code Online (Sandbox Code Playgroud)