删除左值,保留左值引用(标准类型特征可用?)
Remove rvalueness, keep lvalue references (standard type trait available?)
我正试图编写一个函数,以std::tuple
的形式返回变参数包的子集。理想情况下,该函数应该没有运行时开销(没有不必要的副本),并且应该允许用户访问lvalue
引用并修改它们。
应维护值类型、lvalue
引用和const lvalue
引用。临时引用(rvalue
引用)应"转换"为值类型,以避免创建无效引用(对临时引用的引用)。
所需结果示例:
int lr = 5;
const int& clr = lr;
auto t = make_subpack_tuple(lr, clr, 5);
static_assert(is_same
<
decltype(t),
std::tuple<int&, const int&, int>
>{}, "");
// Ok, modifies lr:
std::get<0>(t) = 10;
// Compile-time error, intended:
// std::get<1>(t) = 20;
// Ok, 5 was moved into the tuple:
std::get<2>(t) = 30;
不完整实施示例:
template<typename... Ts>
auto make_subpack_tuple(Ts&&... xs)
{
return std::tuple
<
some_type_trait<decltype(xs)>...
>
(
std::forward<decltype(xs)>(xs)...
);
}
我想做的事情有意义吗?
是否有一种标准类型特征可以用来代替some_type_trait
?还是我应该实施自己的解决方案?
您的解决方案将是
template<typename... Ts>
auto make_subpack_tuple(Ts&&... xs)
{
return std::tuple<Ts...>(std::forward<Ts>(xs)...);
}
根据模板参数推导规则,参数包Ts...
将只包含cv限定类型和lvalue。这个问题中的信息可能也很有用。
我只想指出,在实现Nick Athanasios的可折叠Op<operation>
的有效版本时,我遇到了同样的非绝对问题("我认为我需要衰减右值引用并保持左值引用不变")。我遇到了这样的麻烦:
template<class Pack, class Op>
struct Foldable
{
mystery_trait_t<Pack> value;
const Op& op;
template<class RhsPack>
auto operator*(const Foldable<RhsPack, Op>& rhs) const {
return op(static_cast<std::decay_t<Pack>>(
(op.f)(std::move(value), std::move(rhs.value))
));
}
operator mystery_trait_t<Pack> () && {
return std::move(value);
}
};
template<class Pack>
auto NamedOperator::operator()(Pack&& value) const {
return Foldable<Pack, NamedOperator>(std::forward<Pack>(value), *this);
}
(在困惑了一会儿,然后开始问一个SO问题,找到这个现有的问题/答案,并在我的mystery_trait_t
实现中添加一个static_assert
,以验证它从未真正用右值引用类型调用过!)事实证明,我真正需要的只是
template<class Pack, class Op>
struct Foldable
{
Pack value;
const Op& op;
template<class RhsPack>
auto operator*(const Foldable<RhsPack, Op>& rhs) const {
return op(
(op.f)(std::move(value), std::move(rhs.value))
);
}
operator Pack () && {
return std::move(value);
}
};
(在Wandbox上查看我的全部代码。)
我的这个"答案"没有提供任何新的信息,但我认为分享它会很有用,因为它只是表明,即使你认为你在模板元编程方面有很大的深度,并且确信你需要这种"条件衰减"行为。。。你真的不需要它!
可能有一个必然的一般规则,编写any_template<T&&>
总是一种代码气味在Vittorio最初的问题中,他实际上做了两次,尽管这两次都被decltype
语法所隐藏:
some_type_trait<decltype(xs)>... // should have been `Ts...`
std::forward<decltype(xs)>(xs)... // could equally well be `std::forward<Ts>(xs)...`
- 如何将高维数据映射到特征类型?
- 将平面阵列重塑为复杂的特征类型
- 以特征类型作为参数的泛型函数回调
- 如何通过opencv中的程序参数定义特征类型?
- 在编译时检查特征类型保存的数据在内存中是否连续
- 专门针对特征类型的功能
- 具有特征类型输出的特征二进制 Expr
- 使用具有STL容器和STD :: vector的特征类型
- 从指针进行特征3类型的强制转换/复制(溢出uint8_t)
- 使用 python 扩展在 gdb 中打印特征类型时出现问题
- 将特征类型与 boost::bind 一起使用是否会自动违反 Eigen 的"only pass by reference"规则?
- NVIDIA NVCC 在使用模板特征类型时更改编译时间常量
- 固定大小的特征类型作为参数
- 特征类型类型定义失败,并显示 C4430
- 检查类型是否为特征 3 类型
- 传递std::迭代器,指向具有特征类型的向量
- visual studio 2012中对特征类型向量的自动矢量化表现不佳
- 子类特征类型
- 使用一个特征类型内提升图
- 特征c++类型转换