我经常听到,在编译C和C ++程序时,我应该“始终启用编译器警告”。为什么这是必要的?我怎么做?
有时我也听说我应该“将警告视为错误”。我是不是该?我怎么做?
考虑这个相当无用的程序:
#include <iostream>
int main(int argc, char* argv[]) {
int a = 5;
auto it = [&](auto self) {
return [&](auto b) {
std::cout << (a + b) << std::endl;
return self(self);
};
};
it(it)(4)(6)(42)(77)(999);
}
Run Code Online (Sandbox Code Playgroud)
基本上我们正在尝试制作一个返回自己的lambda.
error: function 'operator()<(lambda at lam.cpp:6:13)>' with deduced return type cannot be used before it is defined
哪个编译器是对的?是否存在静态约束违规,UB或两者都没有?
clang接受更新此轻微修改:
auto it = [&](auto& self, auto b) {
std::cout << (a + b) << std::endl;
return [&](auto p) { return …
Run Code Online (Sandbox Code Playgroud) 我已经开始为我的编程课学习C++了.我已经下载了这个"Hello World"程序:
#include <iostream>
using namespace std;
int main()
{
cout << "Hello, World!";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是Turbo C++抱怨道:
Error D:\HELLO.CPP 1: Unable to open include file 'IOSTREAM'
Error D:\HELLO.CPP 2: Declaration syntax error
Error D:\HELLO.CPP 6: Undefined symbol 'cout'
Run Code Online (Sandbox Code Playgroud)
这个非常简单的程序出了什么问题?我该如何纠正这些错误?
我们从类别理论中知道,并非Set中的所有endofunctors都承认一个免费的monad.规范的反例是powerset仿函数.
但是Haskell可以将任何仿函数变成一个免费的monad.
data Free f a = Pure a | Free (f (Free f a))
instance Functor f => Monad (Free f) where
return = Pure
Pure a >>= f = f a
Free m >>= f = Free ((>>= f) <$> m)
Run Code Online (Sandbox Code Playgroud)
是什么让这个构造适用于任何Haskell仿函数但在Set中分解?
[basic.compound]
如果两个对象是指针可互换的,那么它们具有相同的地址
然后注意到
数组对象及其第一个元素不是指针可互换的,即使它们具有相同的地址
使数组对象及其第一个元素非指针可互换的基本原理是什么?更一般地说,区分指针 - 可互换性概念与具有相同地址的概念的理由是什么?在那里某处不存在矛盾吗?
看来,给定这一系列陈述
int a[10];
void* p1 = static_cast<void*>(&a[0]);
void* p2 = static_cast<void*>(&a);
int* i1 = static_cast<int*>(p1);
int* i2 = static_cast<int*>(p2);
Run Code Online (Sandbox Code Playgroud)
p1 == p2
但是,我们已经i1
明确定义并且使用i2
会导致UB.
考虑一下这个C++ 11程序:
#include <iostream>
template <class A, class B = char> struct Cont {
Cont () { std::cout << sizeof(B); }
};
template <template<class, class = int> class C, class E> class Wrap1
{
C<E> ce;
};
template <template<class, class = int> class C, class... E> class Wrap2
{
C<E...> ce;
};
int main ()
{
Wrap1<Cont, void> w1;
Wrap2<Cont, void> w2;
}
Run Code Online (Sandbox Code Playgroud)
使用gcc或clang编译时,输出为41
.
这种行为是否符合标准?凡究竟该标准规定它(对于Wrap1
和Wrap2
)?
这个问题部分受到另一个问题的启发.
在尝试读取点分隔整数列表时,我注意到了一件奇怪的事情.
Prelude> (reads "123") :: [(Integer,String)]
[(123,"")]
Prelude> (reads "123.") :: [(Integer,String)]
[(123,".")]
Prelude> (reads "123.456") :: [(Integer,String)]
[]
Run Code Online (Sandbox Code Playgroud)
我理解为什么它会在实现方面发生(readNumber
成功然后convert
失败),我理解如何使用readDec
它来克服它.
我的问题是,这种行为是否记录在报告的某个地方?如果是这样,为什么?
考虑这个程序:
#include <iostream>
#include <type_traits>
using namespace std;
struct russell {
template <typename barber,
typename = typename enable_if<!is_convertible<barber, russell>::value>::type>
russell(barber) {}
};
russell verify1() { return 42L; }
russell verify2() { return 42; }
int main ()
{
verify1();
verify2();
cout << is_convertible<long, russell>::value;
cout << is_convertible<int, russell>::value;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果某些类型barber
无法转换为russell
.我们试图通过使其可转换(启用转换构造函数)来创建一个悖论.
输出00
有三个流行的编译器,虽然构造函数显然在工作.
我怀疑行为应该是未定义的,但在标准中找不到任何内容.
该计划的输出应该是什么,为什么?
我(re?)用数据成员语法发明了这种零成本属性的方法.通过这个我的意思是用户可以写:
some_struct.some_member = var;
var = some_struct.some_member;
Run Code Online (Sandbox Code Playgroud)
并且这些成员访问重定向到成员函数,零开销.
虽然初步测试表明该方法在实践中确实有效,但我很难确定它没有未定义的行为.以下是说明该方法的简化代码:
template <class Owner, class Type, Type& (Owner::*accessor)()>
struct property {
operator Type&() {
Owner* optr = reinterpret_cast<Owner*>(this);
return (optr->*accessor)();
}
Type& operator= (const Type& t) {
Owner* optr = reinterpret_cast<Owner*>(this);
return (optr->*accessor)() = t;
}
};
union Point
{
int& get_x() { return xy[0]; }
int& get_y() { return xy[1]; }
std::array<int, 2> xy;
property<Point, int, &Point::get_x> x;
property<Point, int, &Point::get_y> y;
};
Run Code Online (Sandbox Code Playgroud)
测试驱动程序演示了该方法的工作原理并且确实是零成本(属性不占用额外的内存):
int main()
{
Point m;
m.x = …
Run Code Online (Sandbox Code Playgroud) 我们x
是基本的源代码字符集的任何成员.'x'
并且L'x'
分别是基本执行字符集和基本执行宽字符集的成员.
这是真的,积分值'x'
和L'x'
必须相等?看起来标准并不需要,这是有道理的.可以想象,使用说EBCDIC作为窄字符集和Unicode作为宽字符集.
是否std::use_facet<std::ctype<wchar_t>>(std::locale()).widen('x')
应该L'x'
在某些(或任何)区域设置中等于?在这种情况下,要求它是有意义的,但我也无法在标准中找到这样的要求.同样,是std::use_facet<std::ctype<wchar_t>>(std::locale()).narrow(L'x')
一样的'x'
吗?
如果以上不是真的,那么这些中的哪一个
std::wcout << L'x';
std::wcout << ct.widen('x');
Run Code Online (Sandbox Code Playgroud)
应输出x
?ct
是一个合适的区域设置方面.