假设我有一个模板函数:
template <typename A, typename B>
A fancy_cast(B)
{
return {};
}
Run Code Online (Sandbox Code Playgroud)
预期的用法类似于fancy_cast<int>(1.f)。
但是,没有什么可以阻止用户手动指定第二个模板参数:fancy_cast<int, int>(1.f),这会引起问题。
如何防止typename B被指定并强制推断?
我想出了这个:
// Using this wrapper prevents the code from being
// ill-formed NDR due to [temp.res]/8.3
template <auto V> inline constexpr auto constant_value = V;
template <
typename A,
typename ...Dummy,
typename B,
typename = std::enable_if_t<constant_value<sizeof...(Dummy)> == 0>
>
A fancy_cast(B)
{
return {};
}
Run Code Online (Sandbox Code Playgroud)
它似乎可以工作,但是非常麻烦。有没有更好的办法?
我找到了一个不错的解决方案。
我们可以使用用户无法构造的类型的非类型参数包。1例如对隐藏类的引用:
namespace impl
{
class require_deduction_helper
{
protected:
constexpr require_deduction_helper() {}
};
}
using require_deduction = impl::require_deduction_helper &;
template <typename A, require_deduction..., typename B>
A fancy_cast(B)
{
return {};
}
Run Code Online (Sandbox Code Playgroud)
1我们必须在构造 a 时留下一个漏洞deduction_barrier,否则代码将是格式错误的 NDR。这就是构造函数受到保护的原因。
| 归档时间: |
|
| 查看次数: |
114 次 |
| 最近记录: |