如果返回类型是数组,则禁用模板成员函数

pet*_*hen 7 c++ templates sfinae template-argument-deduction

https://www.godbolt.org/z/_4aqsF:

template <typename T> struct Container
{
    template <typename TPred> T find_if(TPred pred);  // the culprit
};

template <typename T> Container<T> MakeContainer(T const &)
{
    return Container<T>();    
}

int main()
{
    auto x = MakeContainer("Hello!");
}
Run Code Online (Sandbox Code Playgroud)

gcc,clang和msvc显然同意这不能编译,因为find_if将返回一个数组.

(我会假设成员模板没有实例化,因为它没有被使用 - 显然,这种简单化的观点是错误的.)

为什么SFINAE不适用于此?

有没有办法排除T不是可退回类型的类型的成员模板?

Jan*_*ans 2

要使用 SFINAE,fidn_if您需要使用函数本身的依赖参数,这是 SFINAE 在不可返回类型上的版本:

template <typename TPred, class U = T, typename std::enable_if<
       std::is_same<T, U>::value
    && !std::is_abstract<U>::value
    && !std::is_function<U>::value
    && !std::is_array<U>::value
    , bool>::type = true>
U find_if(TPred pred);
Run Code Online (Sandbox Code Playgroud)