我的问题如下:为了确定 Windows 平台上的两个路径是否相同,比较路径时不区分大小写,ei。“C:\test.txt”和“C:\Test.txt”解析为相同的文件元素。我可以通过使用std::filesystem::equal示例轻松解决这个问题,但对于这个特定问题,我想在操作系统往返上节省一点(在空闲状态下运行并在每个循环上进行 100 多次比较 - 我担心它会很明显)
using path = std::filesystem::path;
const bool result = (path("C:\\test.txt").lexically_normal().make_preferred().native() == path("C:\\Test.txt").lexically_normal().make_preferred().native());
Run Code Online (Sandbox Code Playgroud)
在比较时std::filesystem::path,即使通过调用进行词法规范化lexical_normal也是以通用方式完成的,因此也会考虑这种情况。这当然是有道理的,但除了我自己进行字符串比较之外,我看不到一种方法可以在不进行比较的情况下使用库来执行此操作:是否有可能以某种方式覆盖路径的比较方式?
我也调查过boost::filesystem,但据我所知也没有解决这个问题。
我知道有一些特殊的规则可以推断出initializer_list,但在发现以下内容之前我认为从来没有.什么时候可以推断或省略initializer_list?
以下示例似乎是不合逻辑的,感觉几乎像语言不足?
#include <initializer_list>
void test() {
bool reverse = true;
const auto ascend = {1,2,3};//OK : seems to deduce to std::initializer_list<const int>
//const auto a_or_d_AUTO = reverse ? {3,2,1} : {1,2,3};//not ok, why ?
const auto i = reverse ? 3 : 1;// also fine
const auto a_or_d = reverse ? std::initializer_list<const int>({3,2,1}) : std::initializer_list<const int>({1,2,3});//also OK
}
Run Code Online (Sandbox Code Playgroud)
我有以下示例:
#include <array>
struct A {
const char* str;
const char* str2;
};
template<size_t N>
struct As {
std::array<A,N> elems_;
};
template<class... Args>
As(Args...)->As<sizeof...(Args)>; //<-- NOTE: deduction guide !
constexpr static As as{A{"a","b"}, A{"1","2"}};//<-- 'retyping' A here
int main() {
return as.elems_.size();
}
Run Code Online (Sandbox Code Playgroud)
尽管此代码有效,但我想避免在A汇总列表中对的“重新键入” ,但是如果不加说明,则推导指南将失败:("cannot deduce template arguments for 'As'"我想这很有意义)。解决此问题的一种方法可能是通过手写我需要的任意数量的扣除指南,此后我可以A在每个扣除指南中编写类型(即:针对我需要的每种尺寸的容器进行一次扣除)。
c++ language-lawyer aggregate-initialization constexpr c++17
explicit可以用于例如。一个构造函数或转换函数,以避免隐式调用该构造函数/转换 - 简而言之。
我想知道是否有可能以某种方式显式地明确单个参数(缺少滚动新类型)?也许使用编译器扩展?
使用引用使复制构造变得不可能,因此这是一种解决方案,尽管不是我正在寻找的解决方案。有时能够explicit在功能级别强制执行将是简洁的工具/界面说明符。
void f(std::string& s); //cannot copy convert into s
void f(const std::string& t);//calling with char* allowed
Run Code Online (Sandbox Code Playgroud)
特别是对于字符串,应该使用什么类型来避免从char*?
我有一些读取 unicode 代码点的代码(在字符串 0xF00 中转义)。
由于我使用boost,我在推测以下是否是最佳(和正确)方法:
unsigned int codepoint{0xF00};
boost::locale::conv::utf_to_utf<char>(&codepoint, &codepoint+1);
Run Code Online (Sandbox Code Playgroud)
?
我有一个接口,我必须在其中传递成员函数指针,这些指针被静态转换为基指针,并在我们的背后存储为 void 指针和调用类型(mfc 消息表)。
我创建了一个包装器来执行一些异常处理(非常简单的 try/catch 来捕获 std::runtime_error),因为这很乏味,并且在每个用户回调中都容易出错。
到目前为止,以下包装器实际上运行得相当好(这个想法是直接获取成员函数指针作为值模板参数- 本质上为每个回调函数提供一个成员函数包装器。):
class MyClass : public CWnd/*example*/{
public:
template<void (MyClass::*f)(CCmdUI*)>
void Dispatch(CCmdUI* pCmdUI) {
try {
(this->*f)(pCmdUI);
}
catch (std::runtime_error& e) {
//handle error
}
}
};
Run Code Online (Sandbox Code Playgroud)
但是为了避免对每种类型的调用进行显式重载 - 是否可以对参数列表进行参数化?
插图(注意这不起作用):
template<void (MyClass::*f)(Args...)>
void Dispatch(Args... args) {
Run Code Online (Sandbox Code Playgroud) c++ templates member-function-pointers variadic-templates c++17
标题几乎说明了一切。
void f(const char*)
Run Code Online (Sandbox Code Playgroud)
到
void f(std::string_view)
Run Code Online (Sandbox Code Playgroud)
安全吗?如果不是,有什么陷阱?
std::string_view语义规定数组不一定是空终止,这可能是内部真正的问题,f因为已经考虑到这一点(例如,如果原始指针被传递到期望在 内终止空的函数f)。
考虑以下代码:
static std::unordered_map<std::string, Info> stringCollection;
auto& [it, inserted] = stringCollection.try_emplace(pString);
if (inserted) {
it->second.str = &it->first;
}
return it->second;
Run Code Online (Sandbox Code Playgroud)
该行it->second.str = &it->first应该复制键(指针)的地址-但我似乎无法验证是否会出现这种情况(找不到引用)。基本上it->first给我副本还是参考?
现在通常应该稀疏使用运算符重载-特别是在涉及stdlib时。
尽管我很好奇,除了读者可能无法清楚地看到代码中正在发生什么的显而易见的隐患之外,还有什么隐患?如果有技术上的原因,可以避免这种特殊的重载吗?
std::string operator+(const std::string& lhs, const std::wstring& rhs) {
return lhs + to_utf8(rhs);
}
Run Code Online (Sandbox Code Playgroud)
(也有用于执行逆变换的双重载)
我发现这可以使某些操作更容易写出来,例如:
std::wstring{L"hel"} + "lo " + getName();
Run Code Online (Sandbox Code Playgroud)
优点和缺点是什么,特别是您看到任何可能“适得其反”的情况(技术上)吗?
性能不是问题。
假设您有一个类型的向量要分配给另一种不同类型的向量?
#include <vector>
int main() {
std::vector ints = {0,1,2,3};
std::vector<long long int> llints = ints;//compile error here
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这怎么可能用一个单行(一个表达式),而不是使用 lambda,只使用std或boost
?
c++ ×10
c++17 ×9
boost ×1
boost-locale ×1
constexpr ×1
explicit ×1
string-view ×1
templates ×1
utf-8 ×1
vector ×1