什么是C ++实例化方法?

我正在尝试使用gcc和clang编译此代码:

#include <iostream>
#include <type_traits>


template<int N>
struct Test
{
    template<typename = std::enable_if_t<N == 1,bool>>
    void func()
    {
        std::cout << "Test::func" << std::endl;
    }
};

int main()
{
    Test<0> t;

    //t.func();
}

所以,我有一个错误:

error: no type named 'type' in 'std::__1::enable_if<false,bool>'; 'enable_if' cannot be used to 
disable this declaration
template <bool _Bp,class _Tp = void> using enable_if_t = typename enable_if<_Bp,_Tp>::type;

但是,如果我使用vc ++编译该代码,则不会出错。 那么,哪个编译器根据c ++标准解决了此问题?

wubinke6108 回答:什么是C ++实例化方法?

这里的GCC和Clang是正确的。

当您编写Test<0>并将N替换为0时。在func的声明中,std::enable_if_t将尝试访问成员::type,不存在。这是一个错误,因为该成员不存在,并且您不能这样声明。

SFINEE的工作方式是在重载解析期间,当编译器执行模板参数推导时,如果模板中的参数替换失败,则不会出现错误,并且该功能从潜在的过载集中被丢弃。在您的示例中,没有模板参数推导。从类模板中已经知道N,因为func的声明在重载解析甚至开始之前就格式不正确。

您的用例可能的解决方法是:

template<int M = N,typename = std::enable_if_t<M == 1,bool>>
void func()
{
    std::cout << "Test::func" << std::endl;
}

这样,func现在取决于函数模板参数M,并且SFINAE可以按预期工作。

本文链接:https://www.f2er.com/3062189.html

大家都在问