【问题标题】:Specialize member func for integral template arg with c++17使用 c++17 将成员 func 专门用于集成模板 arg
【发布时间】:2022-01-01 15:54:01
【问题描述】:

我正在尝试使用 std::enable_if_tstd::is_integral_v 模板来专门化一个类的 mem-func。我读过this,但它是关于通用函数而不是成员函数。

我模仿它并编写我的代码如下,但它不起作用。

namespace oct {

class Class1 {
    template< typename T> T memf();
};

template< typename T>
std::enable_if_t< std::is_integral_v<T>, T> Class1::memf() {
    std::cout << "Integral." << std::endl;
    return 1;
};

template< typename T>
std::enable_if_t < ! std::is_integral_v<T>, T > Class1::memf() {
    std::cout << "None-Integral." << std::endl;
    return T {};
};

};

编译错误消息:

没有声明匹配‘std::enable_if_t oct::Class1::memf()

【问题讨论】:

  • 您不能部分特化函数模板。您需要使用重载而不是专业化。

标签: c++ templates c++17 template-specialization conditional-compilation


【解决方案1】:

如下图所示:

版本 1

#include <iostream>
#include <type_traits>

namespace oct{
class Class1 {
    public:
        template< typename T>
        std::enable_if_t< std::is_integral_v<T>, T> memf() ;
        template< typename T>
        std::enable_if_t < ! std::is_integral_v<T>, T > memf();
};
}
template< typename T>
        std::enable_if_t< std::is_integral_v<T>, T> oct::Class1::memf() {
            std::cout << "Integral." << std::endl;
            return 1;
        }
template< typename T>
        std::enable_if_t < ! std::is_integral_v<T>, T > oct::Class1::memf() {
            std::cout << "None-Integral." << std::endl;
            return T {};
        }
int main()
{
    oct::Class1 f;
    f.memf<int>();//prints "Integral."
    f.memf<int*>();//prints "Non-Integral."
}

第 2 版

#include <iostream>
#include <type_traits>

namespace oct{
class Class1 {
    public:
        template< typename T>
        std::enable_if_t< std::is_integral_v<T>, T> memf() {
            std::cout << "Integral." << std::endl;
            return 1;
        }
        template< typename T>
        std::enable_if_t < ! std::is_integral_v<T>, T > memf() {
            std::cout << "None-Integral." << std::endl;
            return T {};
        }
};

}
int main()
{
    oct::Class1 f;
    f.memf<int>(); //prints "Integral."
    f.memf<int*>();//prints "Non-Integral."
}

另外,请注意函数模板不能部分特化。

我还删除了程序中不必要的 ; 分号。

【讨论】:

    【解决方案2】:

    作为 SFINAE 的替代方案,您可以使用 if constexpr

    class Class1
    {
        template <typename T>
        T memf()
        {
            if constexpr (std::is_integral_v<T>)
            {
                std::cout << "Integral." << std::endl;
                return 1;
            } else {
                std::cout << "Non-Integral." << std::endl;
                return T {};
            }
        }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多