c++ - 指定类模板参数的要求
问题描述
我有几个看起来像这样的课程:
struct neg_inf {
constexpr double operator()() { return -std::numeric_limits<double>::infinity(); }
};
struct pos_inf {
constexpr double operator()() { return std::numeric_limits<double>::infinity(); }
};
template<typename dX, class LowerBound, class UpperBound>
class limit {
dX dx;
UpperBound upperBound;
LowerBound lowerBound;
double step_size;
limit( dX x, LowerBound lower, UpperBound upper, double step = 1 ) :
dx{ x }, lowerBound{ lower }, upperBound{ upper }, step_size{ step }
{}
dX value() const { return dx; }
LowerBound lower() const { return lowerBound; }
UpperBound upper() const { return upperBound; }
double step() const { return step_size; }
};
到目前为止,这些类按预期工作。现在我想使用诸如std::enable_if_t
,之类的条件来修改模板参数std::is_arithemtic
std::is_same
。
这些是实例化限制对象需要满足的条件。
dX
必须至少arithmetic
和numerical
Lower
&Upper
bound
必须是numerical
、arithmetic
或neg_inf
或pos_inf
。
例如,这些是有效的实例化:
dX = 1st and can be any: int, long, float, double, /*complex*/, etc.
limit< 1st, 1st, 1st > // default template
limit< 1st, 1st, pos_inf > // these will be specializations
limit< 1st, 1st, neg_inf >
limit< 1st, pos_inf, 1st >
limit< 1st, neg_inf, 1st >
limit< 1st, pos_inf, pos_inf >
limit< 1st, neg_inf, neg_inf >
limit< 1st, neg_inf, pos_inf >
limit< 1st, pos_inf, neg_inf >
这些是实例化我的模板的有效条件。UpperBound
当and orLowerBound
是一种infinity
类型时,我计划部分专业化这门课。当upper
和lower
边界是数值 - 算术类型时,通用或默认模板将处理它们。
我的问题是图书馆template declaration
的班级会是什么样子?type_traits
解决方案
将模板类型限制为类的一种方法是为 SFINAE 添加额外的参数:
template <typename dX, class LowerBound, class UpperBound, typename Enabler = void>
class limit;
然后,通过适当的 SFINAE 提供专业化
template <typename dX, class LowerBound, class UpperBound>
class limit<dX,
LowerBound,
UpperBound,
std::enable_if_t<my_condition<dX, LowerBound, UpperBound>::value>>
{
// ...
};
所以在你的情况下,my_condition
应该是这样的
template <typename dX, class LowerBound, class UpperBound>
using my_condition =
std::conjunction<std::is_arithmetic<dX>,
std::disjunction<std::is_arithmetic<LowerBound>,
std::is_same<LowerBound, neg_inf>,
std::is_same<LowerBound, pos_inf>>,
std::disjunction<std::is_arithmetic<UpperBound>,
std::is_same<UpperBound, neg_inf>,
std::is_same<UpperBound, pos_inf>>
>;
另一种方式是static_assert
:
template <typename dX, class LowerBound, class UpperBound>
class limit
{
static_assert(std::is_arithmetic<dX>::value, "!");
static_assert(std::is_arithmetic<LowerBound>::value
|| std::is_same<LowerBound, neg_inf>::value
|| std::is_same<LowerBound, pos_inf>::value, "!");
static_assert(std::is_arithmetic<UpperBound>::value
|| std::is_same<UpperBound, neg_inf>::value
|| std::is_same<UpperBound, pos_inf>::value, "!");
// ...
};
推荐阅读
- apache-kafka - Kafka 消费者使用 AWS_MSK_IAM ClassCastException 错误
- openai-gym - ln: 无法访问 '/root/.mujoco': 权限被拒绝
- python - 使用 NLTK 的令牌出现次数
- javascript - 将 vuejs 2 迁移到 3 后,我收到 webpack 错误 Uncaught ReferenceError: vue is not defined
- python - 为什么 CSS_SELECTOR 不会一直定位到 HTML 标签?
- c++ - 下一个更高的数字,具有相同数量的设置位和一些固定位
- javascript - What is the difference between a key and an identifier in JS?
- php - 使用 oauth2 连接到交换帐户时出现 UnauthorizedException - garethp - php-ews
- string - C 尖锐错误和连接字符串不起作用
- python - 无法写入雪花表但没有返回错误