在C++中.我可以将大多数事物声明为const,例如:
变量:const int i=5;
Scala有val i=5,但是这只会阻止重新分配,而不是更改对象,如下例所示:
C++:
const int i[]={1,2,3,4};
i[2]=5; //errorRun Code Online (Sandbox Code Playgroud)
斯卡拉: val a=Array(1,2,3,4)
a(2)=5 //a is now Array(1, 2, 5, 4)
使用成员函数会更糟:
C++:
class Foo {
int i;
int iPlusFive() const {return i+5;}
int incrementI(){ return ++i; }
}
我可以肯定,调用iPlusFive不会改变对象,我不会在const对象上不小心调用incrementI.
当涉及到集合时,C++继续使用const集合的const-correct条纹:简单地将你的向量声明为const而你无法改变它.将a分配non-const vector<Int>给a const vector<Int>,编译器不会复制任何内容,并且会阻止您更改now const集合中的任何内容.
Scala有scala.collection.mutable.whatever和scala.collection.immutable.whatever,你不能只将可变集合转换为不可变集合,而且你仍然可以用非const成员函数更改收集的对象.
为什么scala,它有一个非常好的类型系统,没有任何可比的C++ const-keyword?
编辑:
Margus建议使用import scala.collection.mutable.我的解决方案是使用
import scala.collection.mutable.HashMap
import scala.collection.immutable.{HashMap => ConstHashMap}Run Code Online (Sandbox Code Playgroud)
这将使可变HashMap可用作HashMap和不可变的als ConstHashMap,但我仍然更喜欢C++方法. 在C++ 0x中,可以创建一个constexpr std :: tuple,例如
#include <tuple>
constexpr int i = 10;
constexpr float f = 2.4f;
constexpr double d = -10.4;
constexpr std::tuple<int, float, double> tup(i, f, d);
Run Code Online (Sandbox Code Playgroud)
还可以在运行时查询std :: tuple,例如通过
int i2 = std::get<0>(tup);
Run Code Online (Sandbox Code Playgroud)
但是在编译时无法查询它,例如,
constexpr int i2 = std::get<0>(tup);
Run Code Online (Sandbox Code Playgroud)
将抛出编译错误(至少使用最新的g ++快照2011-02-19).
有没有其他方法在编译时查询constexpr std :: tuple?
如果没有,是否有一个概念上的原因,为什么不应该查询它?
(我知道避免使用std :: tuple,例如,通过使用boost :: mpl或boost :: fusion,但不知何故,如果不在新标准中使用元组类,这听起来是错误的......).
顺便问一下,有人知道为什么
constexpr std::tuple<int, float, double> tup(i, f, d);
Run Code Online (Sandbox Code Playgroud)
编译好,但是
constexpr std::tuple<int, float, double> tup(10, 2.4f, -10.4);
Run Code Online (Sandbox Code Playgroud)
不?
非常感谢提前! - 啦
我知道const在C++ 中使用一个方法意味着一个对象通过该方法是只读的,但它可能仍然会改变.
但是,此代码显然通过const引用(即通过const方法)更改对象.
这段代码在C++中是否合法?
如果是这样:它是否打破const了类型系统的性质?为什么/为什么不呢?
如果没有:为什么不呢?
#include <iostream>
using namespace std;
struct DoBadThings { int *p; void oops() const { ++*p; } };
struct BreakConst
{
int n;
DoBadThings bad;
BreakConst() { n = 0; bad.p = &n; }
void oops() const { bad.oops(); } // can't change itself... or can it?
};
int main()
{
const BreakConst bc;
cout << bc.n << endl; // 0
bc.oops(); // O:) …Run Code Online (Sandbox Code Playgroud) 以下C++ 11程序是否格式错误?
const int x[] = {1,2,3};
static_assert(x[0] == 1, "yay");
int main() {}
Run Code Online (Sandbox Code Playgroud)
gcc和clang似乎这么认为,但为什么不是x[0] == 1一个恒定的表达?
x[0] == 1
subscript operator
*(x+0) == 1
array-to-pointer conversion (int* p = x)
*(p+0) == 1
pointer addition
*p == 1
indirection (lvalue y = x[0])
y == 1
lvalue-to-rvalue conversion:
Run Code Online (Sandbox Code Playgroud)
一个非易失性glvalue(是的,x [0]是glvalue和非易失性)的整数(是的,它有类型const int)或枚举类型引用一个非易失性的const对象(是的它有类型const int)使用前面的初始化(是初始化为1),使用常量表达式初始化(是1是常量表达式)
似乎是真的,x数组的第一个元素满足这些条件.
1 == 1
Run Code Online (Sandbox Code Playgroud)
?
这是编译器错误,标准缺陷,还是我错过了什么?
5.19 [expr.const]的哪一部分说这不是一个常量表达式?
我正在使用一个具有init与其构造函数不同的函数的类的库.每次我创建一个新实例时我都需要调用,例如:
MyClass a;
a.init();
Run Code Online (Sandbox Code Playgroud)
既然init不是const,这就阻止了我创建const实例(我无法写const MyClass a).有没有办法调用init然后从"here out out"声明(我猜对于范围的其余部分)我的变量是const?
这有效,但依赖于不触及原始变量:
MyClass dont_touch;
dont_touch.init();
const MyClass & a = dont_touch;
Run Code Online (Sandbox Code Playgroud) 在关于C++ 17进展的博客上,我阅读了以下内容:
P0007提出一个辅助函数模板as_const,它只需要一个引用并将其作为引用返回const.Run Code Online (Sandbox Code Playgroud)template <typename T> std::add_const_t<T>& as_const(T& t) { return t } template <typename T> void as_const(T const&&) = delete;
为什么const&&删除了重载?
假设我们想通过以下方式声明const成员函数typedef:
typedef int FC() const;
typedef int F();
struct A
{
FC fc; // fine, we have 'int fc() const'
const F fc; // not fine, 'const' is ignored, so we have 'int fc()'
};
Run Code Online (Sandbox Code Playgroud)
由于const被忽略,程序编译得很好.为什么const忽略功能?既然我们可以用这种方式形成const指针,我唯一能想到的就是"C传承".标准是否对此有所说明?
// case 1
const int i = 42;
const auto &k = i;
// case 2
const int i = 42;
auto &k = i;
Run Code Online (Sandbox Code Playgroud)
在此方案中我们是否需要const关键字auto?毕竟,k对自动推导类型的引用()将包括const对象的顶层().所以我相信在两种情况下都会引用一个为constant()的整数.const int ikconst int &k
如果是真的,这是否意味着const auto &k = i;如果1是由编译器代替,只是const int &k = i;(auto被替换为int)?而在案例2中,auto被替换为const int?
我在下面的函数中有一个小的"lambda表达式":
int main()
{
int x = 10;
auto lambda = [=] () { return x + 3; };
}
Run Code Online (Sandbox Code Playgroud)
下面是为上面的lambda表达式生成的"匿名闭包类".
int main()
{
int x = 10;
class __lambda_3_19
{
public: inline /*constexpr */ int operator()() const
{
return x + 3;
}
private:
int x;
public: __lambda_3_19(int _x) : x{_x}
{}
};
__lambda_3_19 lambda = __lambda_3_19{x};
}
Run Code Online (Sandbox Code Playgroud)
由编译器生成的闭包"operator()"是隐式const.为什么标准委员会const默认做到这一点?