如何解决取std :: vector <bool> :: atsize_t结果的地址,如何为C ++ 11修复?
此功能:
template<typename T>
void f(int stack,std::vector<T> *vec,void (*readItemFunc)(int,T*))
{
// omitted irrelevant code
for(size_t i = 0; i < sz; i++)
{
readItemFunc(stack,&vec->at(i));
}
}
由于std::vector<bool>
的专业性而无法编译。 Clang ++报告此编译错误:
没有从
__bit_iterator<std::__1::vector<bool,std::__1::allocator<bool> >,false>
到bool *
的转换
在C ++ 17中,我可以这样做:
template<typename T>
void f(int stack,T*))
{
// omitted irrelevant code
for(size_t i = 0; i < sz; i++)
{
if constexpr(std::is_same<T,bool>::value)
{
T v;
readItemFunc(stack,&v);
(*vec)[i] = v;
}
else
{
readItemFunc(stack,&vec->at(i));
}
}
}
但这是唯一需要C ++ 17的行,而项目的其余部分支持C ++ 11,因此我会尽量坚持使用C ++ 11,直到有意义为止。
考虑到“省略的无关代码”相当长,并且取决于T
,因此,f()
专用于bool
会涉及很多代码重复。
我可以通过什么其他方式为C ++ 11解决此问题?
解决方法
您基本上可以将T v; expression_that_modifies(&v); vec->at(i) = v;
包装在一个类中,其中std::vector<bool>::reference
是在表达式的求值完成时调用的析构函数中分配的。
例如,
template<typename T>
T& wrap_vector_bool_reference(T& p) noexcept {
return p;
}
struct vector_bool_wrapper {
std::vector<bool>::reference ref;
bool real_bool;
vector_bool_wrapper(std::vector<bool>::reference r) noexcept : ref(r),real_bool(r) {}
operator bool&() noexcept {
return real_bool;
}
bool* operator&() noexcept {
return &real_bool;
}
~vector_bool_wrapper() {
ref = real_bool;
}
};
inline vector_bool_wrapper wrap_vector_bool_reference(std::vector<bool>::reference ref) noexcept {
return vector_bool_wrapper(ref);
}
template<typename T>
void f(int stack,std::vector<T> *vec,void (*readItemFunc)(int,T*))
{
// omitted irrelevant code
for(size_t i = 0; i < sz; i++)
{
// No wrapper is applied if `T` isn't `bool`
readItemFunc(stack,&wrap_vector_bool_reference(vec->at(i)));
}
}
如果您有多个语句,则可以使用一个额外的变量:
{
auto&& i = wrap_vector_bool_reference(vec->at(i));
// i is `T&` normally,but `vector_bool_wrapper&&` if `T` is `bool`.
// Can cast `i` to `T&`,like
T& ref = i;
T* ptr = &i;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。