使用enable_if进行模板专门化对于函数和类的行为不同

问题描述 投票:0回答:1

我正在尝试使用类似于此处示例的

enable_if
基于模板参数的类型来专门化函数模板https://en.cppreference.com/w/cpp/types/enable_if

template<typename Type, typename Enabled = void>
void foo(Type t)
{
    std::cout << "primary\n";
    std::cout << std::is_same<decltype(t), A>::value << "\n";
}


template<typename Type, typename std::enable_if_t<std::is_same<Type, A>::value>::type>
void foo(Type t)
{
    std::cout << "specialized\n";
}

但是在这种情况下,仅调用主要定义。如果我尝试对课程做同样的事情

template <class T, class Enable = void> 
struct Foo
{
    static void bar()
    {
        std::cout << "T is blah" << std::endl;
    }
};


template <class T> 
struct Foo<T, typename std::enable_if<std::is_integral<T>::value>::type>
{
    static void bar()
    {
        std::cout << "T is int" << std::endl;
    }
};

它实现了预期的行为:

int main() {
    A a;

    // not specializing
    foo<A>(a); // primary called
    foo(19);   // primary called

    // does specializing
    Foo<int>::bar();  // int specialization is called
    Foo<float>::bar(); // generic is called

    return 0;
}

有人可以向我解释一下这种差异吗?是否有一种方法可以在不使用类的情况下实现所需的行为?

我的代码示例: https://godbolt.org/z/86jsxfqdG

c++ templates sfinae enable-if
1个回答
0
投票

函数模板不能像类模板那样部分特化,它们可以重载。例如

template<typename Type>
typename std::enable_if_t<!std::is_same<Type, A>::value> foo(Type t)
{
    std::cout << "primary\n";
}

template<typename Type>
typename std::enable_if_t<std::is_same<Type, A>::value> foo(Type t)
{
    std::cout << "specialized\n";
}

直播

© www.soinside.com 2019 - 2024. All rights reserved.