首页 > 解决方案 > 如何定义基于 enable_if_t 的重载

问题描述

我想写一个2个重载的模板组合,如下面的代码所示,我希望对2个类型的对象做不同的处理。编译时出现以下错误:

// Error    C2672   'info': no matching overloaded function found
// and
// // Error C2783   'void info(StrType)': could not deduce template argument for '__formal'

代码是:


/// With this commented out, compile fails, while with it uncommented, all cals get 
// in to this void template.
//template<typename T/*,
//typename = void*/>
//void info(T s) {
//
//}

template <typename StrType,
    std::enable_if_t<std::is_convertible_v<std::string, StrType>, bool> = false
>
void info(StrType s) {
    std::cout <<"str: "<< s << std::endl;
}


template<typename IntType,
    std::enable_if_t<std::is_same_v<    
    typename std::remove_reference_t<typename std::remove_cv<IntType>>  , 
    int
    >, bool> = false
>
void info(IntType s) {
    std::cout <<"int: "<< s + s << std::endl;
}

int main() {
    info("31");  // Error   C2672   'info': no matching overloaded function found
// and
// // Error C2783   'void info(StrType)': could not deduce template argument for '__formal'

    info((int)111);  // Same complain as above.
}

我期待输出是 str: 31 int: 111 但编译失败,抱怨:错误 C2672 'info': no matching 重载函数找到

标签: c++c++11templatestemplate-meta-programming

解决方案


请注意,对于std::is_convertible,第一个模板参数是From,第二个是To,因此将模板参数顺序从

template <typename StrType,
    std::enable_if_t<std::is_convertible_v<std::string, StrType>, bool> = false
>
void info(StrType s)

template <typename StrType,
    std::enable_if_t<std::is_convertible_v<StrType, std::string>, bool> = false
//                                         ^^^^^^^^^^^^^^^^^^^^
>
void info(StrType s)

对于第二个重载,你应该得到typefrom std::remove_cv,而不是直接使用它自己;所以改变

template<typename IntType,
    std::enable_if_t<std::is_same_v<    
    typename std::remove_reference_t<typename std::remove_cv<IntType>>  , 
    int
    >, bool> = false
>
void info(IntType s) {

template<typename IntType,
    std::enable_if_t<std::is_same_v<    
    typename std::remove_reference_t<typename std::remove_cv<IntType>::type>  , 
    //                                                               ^^^^^^
    int
    >, bool> = false
>
void info(IntType s) {

或 (C++14 起)

template<typename IntType,
    std::enable_if_t<std::is_same_v<    
    typename std::remove_reference_t<std::remove_cv_t<IntType>>  , 
    //                                             ^^
    int
    >, bool> = false
>
void info(IntType s) {

居住


推荐阅读