将 filesystem::path 元素附加到另一个路径的最佳方法是什么?
What is the best way to append filesystem::path elements to another path?
我正在尝试将 selected 元素从一条路径附加到另一条路径。但是 path.append 方法并不像我期望的那样起作用。查看它的实现,它将接受来自字符串的元素,而不是来自路径的元素,这看起来很奇怪。给定一对 select 一系列路径元素的路径迭代器,我认为无法将其附加到现有路径或使用它来初始化新路径。
#include <filesystem>
using namespace std;
void TestPathAppend()
{
path path1("c:\dir1\dir2");
// Fails - constructor cannot construct a path from selected path elements.
path path2(path1.begin(), path1.end());
// Ok - constructor _can_ construct a path from a random chunk of string.
string random("stuff");
path path3(random.begin(), random.end());
// Fails - path.append cannot append path elements.
path path4;
path4.append(path1.begin(), path1.end());
// Ok. path.append can append elements from a random chunk of string.
string random("someoldcobblers");
path4.append(random.begin(), random.end());
// What I want to do but can't.
path::iterator temp = path1.begin();
advance(temp, 2);
path4.append(temp, path1.end());
}
更一般地说,路径 class 界面似乎设计得很糟糕。它公开了 begin() 和 end() 方法,使遍历路径元素成为可能,给人的印象是它旨在将路径抽象为一组可迭代的路径元素,但没有推送、弹出、追加或构造函数实际上使您能够使用可以迭代的路径元素的方法。它有一个接受迭代器范围对的构造函数和 append() 方法,但它甚至不能接受其他路径迭代器并且仅适用于字符串迭代器,这是完全多余的,因为您已经可以从字符串构造路径并附加一个到另一个的路径,所以那些字符串迭代器方法甚至不启用任何附加功能,它们只是复制已经可用的功能。
我是不是误解了这种类型的用途?
实现我想做的事情的最佳方法是什么?
这是你想做的事情吗?
#include <iostream>
#include <filesystem>
#include <numeric>
int main()
{
path ab("/a/b");
path cdefgh("c/d/e/f/g/h");
auto first = std::next(cdefgh.begin(), 2);
auto last = std::next(cdefgh.begin(), 5);
auto adefh = std::accumulate(first, last, ab,
[](auto p, const auto& part)
{
return p /= part;
});
std::cout << adefh << std::endl;
}
预期结果:
"/a/b/e/f/g"
我发现针对 Boost 实现提出了相同的问题,该解决方案适用于 VS2012。
void TestPathAppend()
{
path path1("c:\dir1\dir2");
path::iterator temp = path1.begin();
advance(temp, 2);
path path2;
while(temp != path1.end())
{
path2 /= *temp;
++temp;
}
}
虽然它确实显得笨拙,但并不真正符合标准库其余部分的设计理念。例如。如果路径公开了标准的可迭代集合接口,我将能够使用复制方法或 back_inserter 迭代器来执行此操作,而不需要手动循环。
我正在尝试将 selected 元素从一条路径附加到另一条路径。但是 path.append 方法并不像我期望的那样起作用。查看它的实现,它将接受来自字符串的元素,而不是来自路径的元素,这看起来很奇怪。给定一对 select 一系列路径元素的路径迭代器,我认为无法将其附加到现有路径或使用它来初始化新路径。
#include <filesystem>
using namespace std;
void TestPathAppend()
{
path path1("c:\dir1\dir2");
// Fails - constructor cannot construct a path from selected path elements.
path path2(path1.begin(), path1.end());
// Ok - constructor _can_ construct a path from a random chunk of string.
string random("stuff");
path path3(random.begin(), random.end());
// Fails - path.append cannot append path elements.
path path4;
path4.append(path1.begin(), path1.end());
// Ok. path.append can append elements from a random chunk of string.
string random("someoldcobblers");
path4.append(random.begin(), random.end());
// What I want to do but can't.
path::iterator temp = path1.begin();
advance(temp, 2);
path4.append(temp, path1.end());
}
更一般地说,路径 class 界面似乎设计得很糟糕。它公开了 begin() 和 end() 方法,使遍历路径元素成为可能,给人的印象是它旨在将路径抽象为一组可迭代的路径元素,但没有推送、弹出、追加或构造函数实际上使您能够使用可以迭代的路径元素的方法。它有一个接受迭代器范围对的构造函数和 append() 方法,但它甚至不能接受其他路径迭代器并且仅适用于字符串迭代器,这是完全多余的,因为您已经可以从字符串构造路径并附加一个到另一个的路径,所以那些字符串迭代器方法甚至不启用任何附加功能,它们只是复制已经可用的功能。
我是不是误解了这种类型的用途?
实现我想做的事情的最佳方法是什么?
这是你想做的事情吗?
#include <iostream>
#include <filesystem>
#include <numeric>
int main()
{
path ab("/a/b");
path cdefgh("c/d/e/f/g/h");
auto first = std::next(cdefgh.begin(), 2);
auto last = std::next(cdefgh.begin(), 5);
auto adefh = std::accumulate(first, last, ab,
[](auto p, const auto& part)
{
return p /= part;
});
std::cout << adefh << std::endl;
}
预期结果:
"/a/b/e/f/g"
我发现针对 Boost 实现提出了相同的问题,该解决方案适用于 VS2012。
void TestPathAppend()
{
path path1("c:\dir1\dir2");
path::iterator temp = path1.begin();
advance(temp, 2);
path path2;
while(temp != path1.end())
{
path2 /= *temp;
++temp;
}
}
虽然它确实显得笨拙,但并不真正符合标准库其余部分的设计理念。例如。如果路径公开了标准的可迭代集合接口,我将能够使用复制方法或 back_inserter 迭代器来执行此操作,而不需要手动循环。