【问题标题】:C++ template with condition for type具有类型条件的 C++ 模板
【发布时间】:2021-12-08 08:01:57
【问题描述】:

我有带模板的课程。我想为其中一个类方法添加模板条件。

这个想法是对于浮点类型,我希望单独的 passed 方法使用一些 epsilon 值来调用它。

有可能吗?我想要的例子:

template<typename ValueType>
class Comparator {
public:

...

bool passed(ValueType actualValue);

template<
    typename ValueType,
    typename = std::enable_if_t<
        std::is_floating_point<std::remove_reference_t<ValueType>>::value
    >
>
bool passed(ValueType actualValue, ValueType eps) { ... }

...

};

环境: Debian 11, C++14, gcc (Debian 10.2.1-6) 10.2.1 20210110

【问题讨论】:

  • 你有错误的方法定义两个函数,然后在调用时使用 type_trait。

标签: c++ templates c++14


【解决方案1】:

是的,您可以这样做:

#include <type_traits>

template<typename ValueType>
class Comparator {
public:

template<
    typename U = ValueType,
    typename = std::enable_if_t<
        !std::is_floating_point<std::remove_reference_t<U>>::value
    >
>
bool passed(ValueType actualValue);

template<
    typename U = ValueType,
    typename = std::enable_if_t<
        std::is_floating_point<std::remove_reference_t<U>>::value
    >
>
bool passed(ValueType actualValue, ValueType eps);

};

Demo.

【讨论】:

【解决方案2】:

您已经完成了大部分任务。为了重载 SFINAE,您需要使用分配了默认值的非类型模板参数,而不是使用默认类型模板参数。

因此,我们将这两个函数都更改为使用具有默认值的非类型参数,然后将以下条件取反:

template<typename ValueType>
class Comparator {
public:

...
template<
    typename T = ValueType,
    std::enable_if_t<
        !std::is_floating_point<std::remove_reference_t<ValueType>>::value,
//      ^- not here, so only non-floating point types allowed
        bool> = true // set the bool to true, this lets us call the function without providing a value for it
>
bool passed(T actualValue) { non floating point code here }

template<
    typename T = ValueType,
    std::enable_if_t<
        std::is_floating_point<std::remove_reference_t<T>>::value,
        bool> = true // set the bool to true, this lets us call the function without providing a value for it
>
bool passed(T actualValue, T eps) { floating point code here }

【讨论】:

  • @Elliott 可能是,但我不确定。从我所见,非类型模板参数版本似乎使用更广泛。
  • @NathanOliver 谢谢你的回复。您能否描述一下,this "bool> = true // 将 bool 设置为 true,这让我们可以在不为其提供值的情况下调用该函数" 是什么意思?
  • @ВалентинНикин 如果没有= true 部分,您将不得不调用类似foo.passed&lt;type_of_parameter, true&gt;(parameter) 的函数。通过= true,我们将std::enable_if_t解析为true的布尔变量设置为foo.passed(parameter)这样的函数
  • @ВалентинНикин,这些 SFINAE 技术是编译器破解。如果您写 = false ,它具有完全相同的效果。它只是一个无名类型参数的默认值。
  • 不适用于Comparator&lt;float&gt;{}.passed(0, 0);
猜你喜欢
  • 2020-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多