【发布时间】:2018-02-01 22:42:37
【问题描述】:
我有一个项目目前锁定在 Visual Studio 2015 中。但是,我想编写尽可能符合标准的代码。
我想使用std::filesystem,但它直到 C++-17 才成为标准。幸运的是,几乎所有东西都可用,就在std::experimental::filesystem::v1 命名空间中。我不喜欢毯子using 指令;我更喜欢完全确定事物的范围,以明确事物的来源。所以我不打算只写一个全局using 声明。需要一些魔法来说服编译器做我想做的事。
这是我的第一次尝试:
#include <filesystem>
#if defined(_MSC_VER) && _MSC_VER <= 1900 // VS 2015
namespace std {
namespace filesystem {
using path = std::experimental::filesystem::v1::path;
}
}
#endif
效果很好,现在可以访问std::filesystem::path。我已经测试过创建和使用path 对象并且它可以工作。
随着我的前进,我知道我需要更多的东西。我想知道是否有办法把整个东西都带进来:
namespace std {
namespace filesystem {
using std::experimental::filesystem::v1;
}
}
这似乎是倒退了一步。似乎什么都看不见。事后看来,我想这是有道理的,因为using 语句的范围以下一行的右大括号结束。
接下来,我想要一个directory_entry。同样的技术似乎有效
namespace std {
namespace filesystem {
using directory_entry = std::experimental::filesystem::v1::directory_entry;
}
}
再次,编译器似乎很高兴。
现在,我想使用std::directory::create_directories。然而,这是一个函数,而不是一个类,所以同样的技术是行不通的。
我认为std::function 可能是为此量身定制的,但我没有运气。我试过了
namespace std {
namespace filesystem {
function<bool(path)> create_directories = std::experimental::filesystem::v1::create_directories;
}
}
编译器说
Error C2440 'initializing': cannot convert from 'overloaded-function' to 'std::function<bool (std::filesystem::path)>'
函数有两个重载(一个接受第二个参数来返回错误代码而不是抛出异常)。
我被困住了。这必须是可能的,但我的 C++-foo 很弱。
【问题讨论】:
-
我认为扩展
std命名空间是未定义的行为。 stackoverflow.com/questions/37541022/… -
@MFisherKDX 我明白,未定义意味着未定义。但是,如果您用
foo替换std,行为将是相同的。在这种情况下,我认为扩展它是合理的,因为我添加的符号在标准的更高版本中。 -
我不认为
using std::filesystem = std::experimental::filesystem::v1有效? -
@jwm .. 好的,我明白了。你能像这个例子一样先转换函数吗? stackoverflow.com/questions/30393285/…
-
@MarkRansom 应该是
namespace std { namespace filesystem = experimental::filesystem::v1; },但我喜欢这个主意。
标签: c++ visual-studio-2015 std-filesystem