我正在为应用程序的自定义选项文件编写c ++解析器.我有一个循环,option=value从文本文件的形式读取行value必须转换为double.在伪代码中,它执行以下操作:
while(not EOF)
statement <- read_from_file
useful_statement <- remove whitespaces, comments, etc from statement
equal_position <- find '=' in useful_statement
option_str <- useful_statement[0:equal_position)
value_str <- useful_statement[equal_position:end)
find_option(option_str) <- double(value_str)
Run Code Online (Sandbox Code Playgroud)
为了处理字符串拆分和传递给函数,我使用std::string_view它是因为它避免了过多的复制并清楚地说明了查看预先存在的段的意图std::string.我已经做了所有事情,指向其中std::string_view value_str确切部分的点useful_statement包含我想要提取的值,但我无法弄清楚从a中读取a double的方法std::string_view.
我知道std::stod哪个不起作用std::string_view.它允许我写
double value = std::stod(std::string(value_str));
Run Code Online (Sandbox Code Playgroud)
然而,这很难看,因为它转换为实际上不需要的字符串,即使它可能在我的情况下没有明显的差异,如果必须从文本中读取大量的数字,它可能会太慢文件.
另一方面,atof因为我无法保证null终止符,所以不起作用.我可以通过在构造它时添加\0来破解它useful_statement,但这会使代码混淆给读者并且如果代码被更改/重构则使其容易破解.
那么,什么是干净,直观和合理有效的方法呢?
我正在观看视频,其中Nicolai说自动失去移动语义为此示例:
template<typename Callable, typename... Args>
auto call(Callable&& op, Args&&... args) {
return std::invoke(std::forward<Callable>(op), std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)
我在想:
这是为什么?
在这个例子中确实保证了 RVO的启动吗?如果是这样,有什么担心搬家的?
根据C ++标准,您不能将临时绑定到非常量引用。由于流输出运算符定义为
template <class CharT, class Traits, class Allocator>
std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os,
const std::basic_string<CharT, Traits, Allocator>& str);
Run Code Online (Sandbox Code Playgroud)
我希望它不能在临时流对象上调用。但是,我尝试了以下操作并获得了意外的结果
#include <fstream>
std::ostream& print(std::ostream &stream) {
stream << "test\n";
return stream;
}
int main() {
std::fstream("") << "test\n";
// print(std::fstream("")); // Doesn't compile, as expected
}
Run Code Online (Sandbox Code Playgroud)
这可以在GCC干线,Clang干线和MSVC 19上进行编译。我什至尝试-pedantic-errors了前两个。尽管从技术上讲这三个都是错误的,但我可能误会了一些东西。
有人可以在标准中找到关于这是否合法的C ++的明确答案吗?
我正在使用外部库(pcl),所以我需要一个不会改变现有函数原型的解决方案.
我正在使用的一个功能生成一个std::vector<int, Eigen::aligned_allocator<int>>.我想要接下来调用的函数需要a const boost::shared_ptr<std::vector<int, std::allocator<int>>>.我不想复制元素,因为它是我代码中已经很慢的关键部分.如果不是因为分配器不匹配,我只需执行以下操作即可绕过shared_ptr要求:
// code that generates std::vector<int, Eigen::aligned_allocator<int>> source
boost::shared_ptr<std::vector<int>> indices(new std::vector<int>);
indices->swap(source);
// use indices as intended
Run Code Online (Sandbox Code Playgroud)
这不能使用MSVC编译器进行编译,因为它无法在这两种向量类型之间进行转换.到目前为止,我所想到的唯一不会复制内容的解决方案是:
// code that generates std::vector<int, Eigen::aligned_allocator<int>> source
boost::shared_ptr<std::vector<int>> indices(new std::vector<int>);
indices->swap(reinterpret_cast<std::vector<int>&>(source));
// use indices as intended
indices->swap(reinterpret_cast<std::vector<int>&>(pcout.points));
Run Code Online (Sandbox Code Playgroud)
注意我需要如何使用索引作为const shared_ptr.我相信分配器不会在交换操作中发挥作用.int也应该不需要对齐任何填充,因为它们已经是32位大小.std :: allocator版本应该能够从对齐版本中读取,因为它只能分配std :: allocator可能已经使用过的内存地址.最后,我换回,因为如果尝试删除未对齐的保留空间,则对齐的分配器可能会崩溃.
我尝试了它并没有崩溃,但这并不是说服我确实它是正确的.安全吗?如果没有,如果对编译器做出某些合理的假设,它是否有条件安全?有没有更明显影响性能的更安全的替代方案?
请不要回复"描述您的代码","不值得"或类似的答案.即使它们适用于此,理论上也存在复制不是可行解决方案的情况,并且该线程应该解决这个问题.
类似的问题是谈论以清晰的方式复制数据,如评论中所阐明的那样.
编辑:似乎尽管Eigen :: aligned_allocator设计用于16位对齐,但没有额外的填充添加到整数.比较列表中第一个和最后一个元素的地址给出了元素数量和sizeof(int)的大小.这意味着int以一种应该与std :: allocator版本兼容的方式存储.我希望我今天晚些时候或在未来几天有时间做一个更完整的测试.
我想定义一个通用函数,其参数和返回类型是模板的相同实例。这导致过于冗长的定义。有没有一种方法可以使用速记而不污染封闭的名称空间?
例,
template<class CoordinateType, class ValueType>
struct PointWithValue {
CoordinateType x, y;
ValueType value;
}
template<class CoordinateType, class ValueType>
PointWithValue<CoordinateType, ValueType> interpolate(
PointWithValue<CoordinateType, ValueType> point1,
PointWithValue<CoordinateType, ValueType> point2)
{
...
}
Run Code Online (Sandbox Code Playgroud)
我可以提出的一种解决方案是
template<class PointWithValueType>
PointWithValueType interpolate(
PointWithValueType point1, PointWithValueType point2)
Run Code Online (Sandbox Code Playgroud)
但是我对此并不满意,因为它混淆了我的期望PointWithValueType; 它仅隐式显示在body函数内部。而且,如果调用者传递了错误的参数,则错误不太可能清晰明了。
我想要看起来像这样的东西
template<class CoordinateType, class ValueType>
using PointWithValueType = PointWithValue<CoordinateType, ValueType>;
PointWithValueType interpolate(
PointWithValueType point1, PointWithValueType point2)
Run Code Online (Sandbox Code Playgroud)
据我所知,上述内容仅在将其包装在类中并将方法定义为时才有效static。这种方法可以工作,但它也可以更改接口(将函数放在更深的命名范围内),并且它依赖于一个没有成员的类,并且只有一个静态函数,这会使用户感到尴尬并可能使用户感到困惑。
这是一个普遍的问题,不适用于此类问题的解决方法不适用于该特定问题。是否有与我的using示例相似但没有缺点的内容?
我有一些数据类型的数组T,我必须执行一些数据类型long_calculation(const T&)并找到它的最小值.因为该数组非常大并且该函数需要大量的运行时间,所以我希望以多线程方式并以最有效的方式完成.最接近我正在寻找的东西似乎是,std::min_element但它不是一个完美的契合,因为它似乎没有在内部使用它计算的值,它甚至没有返回我想要的值.这迫使我做以下事情.
const auto iter = std::min_element(std::execution::par_unseq,
my_container.begin(), my_container.end(), [](const T& t1, const T& t2) {
return long_calculation(t1) < long_calculation(t2);
}
const auto value = long_calculation(*T1);
Run Code Online (Sandbox Code Playgroud)
标准保证最多N-1比较,但没有存储long_calculation我期望2N-2计算的结果而不是最优N.或者更确切地说是2N-1,因为最后一行.
另一方面,预先计算值并进行搜索确实是N long_calculations但使用O(N)额外的存储空间,在我的情况下也必须动态分配.
有没有办法在标准或某些第三方库中以通用方式执行此操作?如果没有,最合适的方法是什么?理想的解决方案是多线程函数,可以像这样调用.
const auto min_value = min_of_transform(
my_container.begin(), my_container.end(), long_calculation);
Run Code Online (Sandbox Code Playgroud) 如果一个类T具有对齐要求,例如由alignas关键字指定的对齐要求,std::optional<T>并且boost::optional<T>保证尊重所述对齐?
如果它们只是T对象和a的包装类bool initialized,那么它们会T根据需要自动对齐它们的成员,但标准和boost文档声明它们不能容纳任何对象并且很好地处理昂贵的构造对象.据我所知,他们不仅仅包含一个T.相反,它们似乎分配了一个缓冲区,T手动构造或销毁它.因此,C++语言不会自动对齐缓冲区,因为它不是类型T.
那么,做std::optional<T>并boost::optional<T>正确对齐他们的托管T对象?他们是否也提供optional<T>::operator new并optional<T>::operator new[]尊重对齐要求?
c++ ×7
c++17 ×3
boost ×2
templates ×2
allocator ×1
auto ×1
min ×1
performance ×1
stdoptional ×1
string-view ×1
vector ×1