【发布时间】:2020-08-21 10:32:28
【问题描述】:
假设我有以下代码,其中bar 在另一个库中定义:
void bar(int x); /* this declaration comes from some included header file */
void foo(long long y)
{
return bar(y);
}
为了使故障可检测,GSL 指示我使用gsl::narrow,如下所示:
void bar(int x); /* this declaration comes from some included header file */
void foo(long long y)
{
return bar(narrow<int>(y));
}
我的问题是,假设我知道void bar(long long x); 可能会出现在库的未来版本中,第一个版本会自动切换到使用它(通过推演规则),而第二个版本不会。有什么方法可以在void bar(long long x); 不可用时检测到缩小失败,并在释放时切换到仅调用它?
我试过了:
-
bar(narrow(y));,但是无法推导出narrow的模板参数。 -
bar(superint{y}),其中 superint 是struct {long long x;},对于long long和int,具有重载类型转换运算符,后者具有窄检查。这是我最好的主意,因为当添加void bar(long long x);时它会给出ambiguous call编译时错误,让我们知道在适当的时候更新代码库的地方。不过,它看起来不像你会放在 GSL 中的东西,所以我不太满意..
更新
有很多好的答案,但它们都必须按函数而不是按参数来实现。理想情况下,解决方案应该类似于 GSL,您只需对有缩小风险的论点做一些事情。访问者模式在这里可能很有用,我们只需将 quz(xi,yi,z,w) 重写为 superint_visit(quz, superint{xi},superint{xi},z,w); 假设 xi 和 yi 是有缩小风险的整数参数。比如:
struct superint
{
long long x;
operator long long() { return x; }
operator int() { return narrow<int>(x); }
};
template <typename F, typename... Args>
auto superint_visit(F func, Args&&... args)
{
/* if replacing 'superint' with 'long long' in Args
gives a function that is declared, call that function
(using static_cast<long long> on all 'superint' args
to resolve ambiguity). Otherwise, use static_cast<int>
on all 'superint' args and call that function instead. */
}
以上所有内容都可以存在于gsl 命名空间中,我只需将我的函数编写为:
void foo(long long x)
{
return superint_visit(bar, superint{x});
}
即使我在这里接受了答案,我仍然希望听到任何可以实现上述目标的人的意见!
【问题讨论】:
-
如何将 bar 设为模板?这样你就可以调用 bar(y) 并在 bar 实现中做出所有与大小相关的决定。对于它的客户,bar 应该能够处理任何整数类型。我认为这就是您基本上要寻找的。span>
-
不是我的图书馆@StPiere
标签: c++ guideline-support-library