C++ 11中引入了一个非常方便的特性,称为原始字符串文字,它是没有转义字符的字符串.而不是写这个:
regex mask("\\t[0-9]+\\.[0-9]+\\t\\\\SUB");
Run Code Online (Sandbox Code Playgroud)
你可以简单地写一下:
regex mask(R"(\t[0-9]+\.[0-9]+\t\\SUB)");
Run Code Online (Sandbox Code Playgroud)
更具可读性.但是,请注意字符串周围的额外括号,以定义原始字符串文字.
我的问题是,为什么我们甚至需要这些呢?对我来说,它看起来很丑陋和不合逻辑.以下是我看到的缺点:
这就是我所说的难以区分的意思:
"good old usual string literal"
^- body inside quotes -^
R"(new strange raw string literal)"
^- body inside parenthesis -^
Run Code Online (Sandbox Code Playgroud)
以下是专业人士:
"delim( can use "()" here )delim"但是,嘿,如果你需要更多的灵活性,你有旧的好逃脱字符串文字.为什么标准委员会决定用这些绝对不必要的括号来污染每个原始字符串文字的内容?那背后的理由是什么?我没有提到的专业是什么?
UPD Kerrek的答案很棒,但不幸的是,这不是一个答案.因为我已经描述过我理解它是如何工作的,它给了什么好处.自从我提出这个问题五年过去了,仍然没有答案.我仍然对这个决定感到沮丧.可以说这是一个品味问题,但我不同意.你使用了多少个空格,你如何命名你的变量,是这个SomeFunction()还是some_function()- 这是品味问题.而且我可以轻松地从一种风格切换到另一种风格.
但是这个?经过这么多年后仍然感到尴尬和笨拙.不,这不是味道.这是关于我们如何想要涵盖所有可能的情况,无论如何.每当我们需要编写特定于Windows的路径,或正则表达式或多行字符串文字时,我们注定要编写这些丑陋的parens.为了什么?..对于那些我们实际需要放入"字符串的罕见情况?我希望我参加委员会会议,他们决定这样做.我强烈反对这个非常糟糕的决定.我希望.现在我们注定了.
感谢您阅读此内容.现在我觉得好一点.
UPD2以下是我的备选方案,我认为两者都比现有方案好很多.
提案1.灵感来自python.不能使用三引号支持字符串文字:R"""Here is a string literal with any content, except for triple quotes, which you don't actually use that often."""
提案2.受常识的启发.支持所有可能的字符串文字,就像当前的一样:R"delim"content of string"delim".用空分隔符:R""Looks …
最近提出了C++核心指南(恭喜!),我担心gsl::not_null类型.如I.12中所述:声明一个不能为null的指针not_null:
帮助避免解除引用nullptr错误.通过避免对nullptr进行冗余检查来提高性能.
...
通过声明源代码中的意图,实现者和工具可以提供更好的诊断,例如通过静态分析查找某些类错误,并执行优化,例如删除分支和空测试.
目的很明确.但是,我们已经有了语言功能.不能为null的指针称为引用.虽然引用一旦创建就无法反弹,但这个问题可以解决std::reference_wrapper.
我gsl::not_null和之间的主要区别在于,std::reference_wrapper后者只能用于代替指针,而前者适用于任何事物 - 可nullptr分配(引自 F.17:使用not_null来表示"null"不是有效值):
not_null不只是内置指针.它的工作原理为array_view,string_view,unique_ptr,shared_ptr,和其他类似指针的类型.
我想象功能比较表如下:
T&:
nullptr?- 是的std::reference_wrapper<T>:
nullptr?- 是的gsl::not_null<T*>:
nullptr?- 是的现在这里是问题,最后:
std::reference_wrapper现在没用了?PS我创建了标签cpp-core-guidelines,guideline-support-library为此,我希望正确.
我正在尝试使用给定的函数在编译时填充2D数组.这是我的代码:
template<int H, int W>
struct Table
{
int data[H][W];
//std::array<std::array<int, H>, W> data; // This does not work
constexpr Table() : data{}
{
for (int i = 0; i < H; ++i)
for (int j = 0; j < W; ++j)
data[i][j] = i * 10 + j; // This does not work with std::array
}
};
constexpr Table<3, 5> table; // I have table.data properly populated at compile time
Run Code Online (Sandbox Code Playgroud)
它运行得很好,table.data在编译时正确填充.
然而,如果我改变普通2D阵列int[H][W]与std::array<std::array<int, H>, W> …
我们可以在C++ 11中以两种方式初始化变量
一:
int abc = 7;
Run Code Online (Sandbox Code Playgroud)
二:
int abc {7};
Run Code Online (Sandbox Code Playgroud)
这两种方法有什么区别?
编译器如何区别对待它们或执行这些代码的方式?
我无法想出一个适当的问题标题来描述问题.希望下面的细节清楚地解释了我的问题.
请考虑以下代码
#include <iostream>
template <typename Derived>
class Base
{
public :
void call ()
{
static_cast<Derived *>(this)->call_impl();
}
};
class D1 : public Base<D1>
{
public :
void call_impl ()
{
data_ = 100;
std::cout << data_ << std::endl;
}
private :
int data_;
};
class D2 : public Base<D1> // This is wrong by intension
{
public :
void call_impl ()
{
std::cout << data_ << std::endl;
}
private :
int data_;
};
int main ()
{
D2 …Run Code Online (Sandbox Code Playgroud) 我最近通过Herb Sutter获得了"Exceptional C++",我对他在第6项 - 临时对象中提出的特别建议表示严重怀疑.
他提供了在以下代码中查找不必要的临时对象:
string FindAddr(list<Employee> emps, string name)
{
for (list<Employee>::iterator i = emps.begin(); i != emps.end(); i++)
{
if( *i == name )
{
return i->addr;
}
}
return "";
}
Run Code Online (Sandbox Code Playgroud)
作为示例之一,他建议预先计算emps.end()循环之前的值,因为每次迭代都会创建一个临时对象:
对于大多数容器(包括列表),调用end()返回一个必须构造和销毁的临时对象.因为值不会改变,所以在每次循环迭代中重新计算(并重建和重新描述)它都是不必要的低效和不美观的.该值应仅计算一次,存储在本地对象中,然后重复使用.
他建议用以下内容代替:
list<Employee>::const_iterator end(emps.end());
for (list<Employee>::const_iterator i = emps.begin(); i != end; ++i)
Run Code Online (Sandbox Code Playgroud)
对我来说,这是不必要的并发症.即使用compact替换丑陋的类型声明auto,他仍然会获得两行代码而不是一行代码.更重要的是,他end在外部范围内有这个变量.
我确信现代编译器无论如何都会优化这段代码,因为我实际上const_iterator在这里使用并且很容易检查循环内容是否以某种方式访问容器.编译器在过去的13年里变得更聪明,对吧?
无论如何,i != emps.end()在大多数情况下,我更喜欢第一个版本,我不太担心性能.但我想知道,这是否是一种我可以依靠编译器进行优化的结构?
更新
感谢您就如何更好地制作这些无用的代码提出建议.请注意,我的问题是关于编译器,而不是编程技术.现在唯一相关的答案来自NPE和Ellioh.
我是SonarQube的新手,我开始阅读文档,但很多时候发现"泄漏期",但我没有发现任何关于它的事情,有人可以解释一下这意味着我的第二个问题是什么是声纳 - 跑步者的作用?我发现它很多时候我正在搜索声纳安装,即使我已经安装了sonarQube并将其与我的项目联系使用maven-sonar插件和eclipse插件sonarLint谢谢你
我正在玩SFINAE并发现我无法解释的行为.
这编译正常:
template<typename Integer,
std::enable_if_t<std::is_integral<Integer>::value>* = nullptr>
void foo(Integer) {}
template<typename Floating,
std::enable_if_t<std::is_floating_point<Floating>::value>* = nullptr>
void foo(Floating) {}
Run Code Online (Sandbox Code Playgroud)
虽然这个(nullptr替换为0):
template<typename Integer,
std::enable_if_t<std::is_integral<Integer>::value>* = 0>
void foo(Integer) {}
template<typename Floating,
std::enable_if_t<std::is_floating_point<Floating>::value>* = 0>
void foo(Floating) {}
Run Code Online (Sandbox Code Playgroud)
prog.cpp: In function ‘int main()’: prog.cpp:13:10: error: no matching function for call to ‘foo(int)’
foo(3);
^ prog.cpp:5:6: note: candidate: template<class Integer, std::enable_if_t<std::is_integral<_Tp>::value>* <anonymous> > void foo(Integer) void foo(Integer) {}
^~~ prog.cpp:5:6: note: template argument deduction/substitution failed: prog.cpp:4:64: …Run Code Online (Sandbox Code Playgroud) Scott Meyers在他的新书"Effective Modern C++"中将以下函数显示为使用示例decltype(auto)(第28页):
template<typename Container, typename Index>
decltype(auto)
authAndAccess(Container&& c, Index i)
{
authenticateUser();
return std::forward<Container>(c)[i];
}
Run Code Online (Sandbox Code Playgroud)
我的问题很简单.为什么我们需要std::forward在c这里申请?我们没有经过c任何地方,我们正在呼吁operator[]它.并且没有一个标准容器具有ref-qualified重载(r值/ l值重载)operator[].
所以我认为只有两个原因std::forward:
operator[].std::forward它.期.还有其他原因吗?
有一个NYES或NO问题的测试.您可以编写测试,教授会告诉您有多少答案是正确的.通过测试的最快方法是什么?即以最少的试验次数给出所有问题的正确答案.
UPDN+1试验的解决方案是显而易见的.在每次试验中,我们都会对一个问题有正确答案.它是1位信息.但教授每次给我们一个从0到N的数字,它是log 2(N + 1)位的信息.这就是为什么最好的解决方案具有O(N / log(N))复杂性.我正在寻找具有亚线性最差时间复杂度的任何解决方案.