考虑这个最小的例子(我能想到):
struct Bar;
struct Foo {
Bar* const b;
Foo(Bar* b) : b(b) {}
};
struct Bar {
Foo* const f;
Bar(Foo* f) : f(f) {}
};
struct Baz : Bar {
Baz() : Bar(new Foo(this)) {}
};
Run Code Online (Sandbox Code Playgroud)
当传递this给ctor时Foo,没有Baz创建层次结构中的任何内容,但是它们既Foo没有Bar收到也没有任何问题.
现在的问题是,this以这种方式放弃或者未定义的行为是否危险?
问题2:如果Foo::Foo(Bar*)是Foo::Foo(Bar&)用相同的语义?我必须通过*this,但deref运算符在这种情况下不会做任何事情.
我只是读了一个人用一个构造函数和operator()一个谓词来调用一个类:
// Example
class Foo {
public:
Foo(Bar);
bool operator()(Baz);
private:
Bar bar;
};
Run Code Online (Sandbox Code Playgroud)
但是,我之前没有听过谓语在这种情况下被使用过.我会称这样的东西为仿函数.对我来说,谓词将来自形式逻辑领域.
这提出了以下问题:
Foo吗?bool与其他东西相比)是否与它有关?operator()存在const?我试图向const一些新代码介绍一些正确性(实际上是函数范例),并发现我无法将std::shared_ptr<A>一个函数传递给期望的函数std::shared_ptr<A const>.请注意,我不想抛弃 const而是引入它,这对于原始指针是合法的.
有办法解决这个问题吗?我没有找到成员函数来执行此操作.
g ++ 4.6.1发出的确切错误是:
error: no matching function for call to ‘foo(std::shared_ptr<A>)’
note: candidate is:
note: template<class T> std::shared_ptr<_Tp> foo(std::shared_ptr<const _Tp>)
Run Code Online (Sandbox Code Playgroud) 我可以更改工作区的名称,并且可能只是通过更改此常量来添加更多:
myWorkspaces = ["1","2","3?","4","5","6","7?","8?","9?"]
Run Code Online (Sandbox Code Playgroud)
如果我向数组添加内容,将会有更多工作空间,但我如何键入它们?Mod-1到Mod-9是默认设置,但我找不到有关如何更改默认值的文档.
我喜欢使用std::ostrstream格式化文本但不将其打印到stdout,而是将其写入std::string(通过访问std::ostrstream::str()成员).显然现在已经弃用了.那么,我应该如何将格式化对象写入字符串,与写入流时一样方便?
这样的模式:
front :: [a] -> a
front (x:_) = x
front _ = error "Empty list"
Run Code Online (Sandbox Code Playgroud)
似乎在Haskell中很常见,但我特别记得在我开始学习Haskell时学习以下内容:
dec :: (Integral a) => a -> a
dec (x+1) = x
dec _ = error "Bottom"
Run Code Online (Sandbox Code Playgroud)
但是,ghc似乎拒绝了那段代码,说明:
Parse error in pattern: x + 1
虽然hugs接受它就好了.那么,这是否是有效的Haskell以及为什么这些编译器的行为不同.
请考虑以下陈述
volatile int a = 7;
a; // statement A
volatile int* b = &a;
*b; // statement B
volatile int& c = a;
c; // statement C
Run Code Online (Sandbox Code Playgroud)
现在,我一直试图在标准中找到一个点,告诉我编译器在遇到这些语句时的行为方式.我能找到的只是A(可能是C)给我一个左值,B也是如此:
标识符是一个id表达式,只要它已被适当声明(第7条).[..]
[..]结果是由标识符表示的实体.如果实体是函数,变量或数据成员,则结果是左值,否则为prvalue.
[..]
一元*运算符执行间接:它所应用的表达式应该是指向对象类型的指针,或指向函数类型的指针,结果是指向表达式指向的对象或函数的左值.
我用clang ++ 3.2-11和g ++ 4.7.3尝试了这个,第一个用C++ 11模式产生三个读取,在C++ 03模式下产生零读取(输出三个警告),而g ++只产生前两个,显式警告我不会生成第三个.
很明显,从标准中的引用行中,哪种类型的值来自表达式,但是:
根据C++标准,哪些语句(A,B,C)应该从易失性实体中产生读取?
假设我有一个包装类型
template <typename T>
struct X {/*..*/};
Run Code Online (Sandbox Code Playgroud)
我不能X(X&&) = default因为我必须在那里做非平凡的事情.
不过,我希望它是noexcept,但只有在这种情况下T(T&&)是noexcept.这可以测试::std::is_nothrow_move_constructible.
我不知道如何有条件地启用一个版本的构造函数或另一个版本取决于a constexpr.我想可能有办法使用SFINAE,但我不知道如何将它应用于ctors.
我有什么保证可能包含 constexpr 函数调用的核心常量表达式(如在 [expr.const].2 中)将在编译时实际评估,这取决于哪些条件?
constexpr通过将计算移至翻译阶段(编译时),引入隐式承诺提高运行时性能。这两点似乎相互矛盾。
在什么情况下可以依靠编译器在编译时解析核心常量表达式(可能包含任意复杂的计算)而不是将其推迟到运行时?
至少在-O0gcc下似乎实际上发出代码并调用 constexpr 函数。在-O1最多不。
难道我们不得不求助于挂羊头卖狗肉,如这个,那个力量通过模板系统constexpr:
template <auto V>
struct compile_time_h { static constexpr auto value = V; };
template <auto V>
inline constexpr auto compile_time = compile_time_h<V>::value;
constexpr int f(int x) { return x; }
int main() {
for (int x = 0; x < compile_time<f(42)>; ++x) {}
}
Run Code Online (Sandbox Code Playgroud) 据的ios_base操纵,我基本上之间的选择defaultfloat和fixed不带指数的符号格式浮点数时(有小数).
但是,我想选择最大精度,它会为许多数字产生很多尾随零fixed(例如1.),但避免使用指数表示法.如果设置为defaultfloat,它将在大多数时间看起来正确,除非值非常小,但不是0..在这种情况下,默认表示单独切换到科学记数法,这打破了格式化输出的接收者(因为它不知道是什么2.22045e-16意思.
那么,我怎么能吃馅饼呢?也就是说,没有不必要的尾随零的非指数表示法.
注意:我没有测试defaultfloat标志的效果,因为我的gcc似乎没有实现那个标志(但是),但我认为它是默认设置,适用时不使用任何标志.我确实检查了fixed标志,它确实按预期运行.
c++ ×8
haskell ×2
c++11 ×1
c++20 ×1
compilation ×1
constexpr ×1
constructor ×1
deprecated ×1
desktop ×1
functor ×1
ghc ×1
hugs ×1
iostream ×1
noexcept ×1
predicate ×1
shared-ptr ×1
standards ×1
stream ×1
terminology ×1
this ×1
volatile ×1
xmonad ×1