使用默认参数转发引用
Forwarding Reference with default argument?
我在尝试弄清楚如何为转发引用(以前由 Scott Meyers 称为通用引用)指定默认参数时遇到麻烦。
下面是尝试执行我想执行的操作的代码示例:
struct encoder_t {
} const encoder = {};
struct validator_t {
} const validator = {};
struct test {
template <typename Range, typename Encoding, typename Validation>
test ( Range&& range, Encoding&& encoding = encoder, Validation&& validation = validator ) {
}
};
int main() {
test( "woof" );
}
也可在科利鲁上找到。
通过这些错误,您会发现可以通过默认模板参数来使其工作,然后默认构造参数:
// Works! But the syntax is strange... potential ramifications/deduction mishaps?
// Is this the "proper" way to default these arguments?
template <typename Range, typename Encoding = encoder_t, typename Validation = validator_t>
test ( Range&& range, Encoding&& encoding = Encoding(), Validation&& validation = Validation() ) {
}
同样在科利鲁。
这是处理这个问题的"正确"方式吗?我应该使用什么语法?是否有多种方法可以达到"默认转发引用"的预期效果?我应该用哪种方式写这篇文章?还要记住,稍后我将在代码上撒上大量的 SFINAE,所以我更喜欢不包括编写多个重载的东西。
首先,模板类型不能从默认参数中推导出来。因此,我们只能寻找其他方法来实现能够选择性地指定参数以匹配转发引用的想法。
此解决方法建议自己:
template <typename Range, typename Encoding = encoder_t, typename Validation = validator_t>
test ( Range&& range, Encoding&& encoding = encoder, Validation&& validation = validator )
{
}
但是,这将失败:转发引用的工作原理是将模板类型推断为引用类型,但您已指定对象类型;并且右值引用现在无法绑定到虚拟对象的左值。
正如您在帖子中所说,您可以通过将默认值设置为临时对象encoder_t{}
而不是虚拟对象来解决此问题。此问题确认在这种情况下,引用确实仍然是转发引用。
另一种解决方法是使用单独的构造函数而不是默认参数:
template <typename Range>
test ( Range&& range )
{
}
template <typename Range, typename Encoding>
test ( Range&& range, Encoding&& encoding )
{
}
template <typename Range, typename Encoding, typename Validation>
test ( Range&& range, Encoding&& encoding, Validation&& validation )
{
}
根据您在构造函数主体中执行的操作,可以使用构造函数委托来实现这一点。
既然你提到了添加SFINAE的意图,也许这篇文章会有一些想法:在构造函数中使用通用引用时如何允许默认构造
相关文章:
- 正在折叠转发引用
- C++ 何时使用常量引用而不是转发引用
- 模板模板参数和转发引用
- 常量转发引用给出错误 C2440:"正在初始化":无法从"常量标准::字符串"转换为"常量标准::字符串 &&"
- 具有右值引用,而不是使用可变参数模板转发引用
- 自定义类型转换运算符在转发引用上调用时不起作用(当对象按值传递时有效)
- 结构化绑定和转发引用是否混合良好?
- 如何声明接受转发引用并返回引用或副本的函数模板
- 间接转发引用
- 为什么调用转发引用构造函数而不是复制构造函数?
- 为什么 std::get 没有一个接受转发引用的签名
- 对 std::Optional 的转发引用构造函数的约束
- 为什么在这种情况下转发引用不起作用?
- 为什么 std::转发是转发引用所必需的
- 将一包转发引用包装成元组
- 涉及在接口中转发引用的重载
- 将转发引用作为lambda捕获传递
- 是否可以在没有类型推断的情况下实现类似转发引用的行为
- 使用确定类型转发引用行为
- 显式模板实例化和转发引用