C#中的引用与C++中的引用非常相似,只是它们是垃圾回收的.
为什么C#编译器支持以下内容如此困难:
const.const,通过它只能const调用成员函数?我相信如果C#支持这个会非常有用.首先,它真的有助于看似广泛的同性恋放弃C#程序员返回裸体引用私人数据(至少这是我在我的工作场所看到的).
或者在C#中我已经缺少了相同的东西?(我知道关键字readonly和const关键字,但它们并没有真正满足上述目的)
我最近与另一位C++开发人员就以下用途进行了交流const:
void Foo(const int bar);
Run Code Online (Sandbox Code Playgroud)
他认为const以这种方式使用是很好的做法.
我认为它对函数的调用者没有任何作用(因为参数的副本将被传递,因此对于覆盖没有额外的安全保证).此外,这样做可以防止实现者Foo修改其参数的私有副本.因此,它既要求又要宣传实施细节.
不是世界末日,但肯定不是值得推荐的良好做法.
我很好奇别人对这个问题的看法.
好吧,我没有意识到参数的常数没有考虑到函数的签名.因此,可以const在实现(.cpp)中标记参数,而不是在标题(.h)中标记- 并且编译器就可以了.既然如此,我想政策应该与制作局部变量const相同.
人们可以提出这样的论点:在标题和源文件中具有不同的看起来签名会使其他人感到困惑(因为它会使我感到困惑).虽然我试着用我写的任何内容来遵循最小惊讶原则,但我认为期望开发人员认为这是合法且有用的是合理的.
什么是向编译器指示的最简单和最不突兀的方式,无论是通过编译器选项,#defines,typedefs还是模板,每次我说T,我的意思是T const什么?我宁愿不使用外部预处理器.由于我不使用mutable关键字,因此可以接受重新调整以指示可变状态.
编辑:由于这个意图完全是错误的(因为我不在几个小时内澄清),让我解释一下.本质上,我只想知道在编译时可以使用哪些系统来操作类型系统.我不在乎这是否会产生非标准,错误,不可维护,无用的代码.我不打算在生产中使用它.这只是一种好奇心.
到目前为止的潜在(次优)解决方案:
// I presume redefinition of keywords is implementation-defined or illegal.
#define int int const
#define ptr * const
int i(0);
int ptr j(&i);
typedef int const Int;
typedef int const* const Intp;
Int i(0);
Intp j(&i);
template<class T>
struct C { typedef T const type; typedef T const* const ptr; };
C<int>::type i(0);
C<int>::ptr j(&i);
Run Code Online (Sandbox Code Playgroud) c++ functional-programming const immutability language-extension
变量的const限定如何在C和C++中有所不同?
"提出这个问题的原因是这个答案:https://stackoverflow.com/questions/4024318#4024417其中他声明const"just"在C中意味着只读.我认为所有const都意味着,无论它是C还是C++.他是什么意思?"
允许这样做的背后的设计理由是什么?
const Foo& a = function_returning_Foo_by_value();
Run Code Online (Sandbox Code Playgroud)
但不是这个
Foo& a = function_returning_Foo_by_value();
Run Code Online (Sandbox Code Playgroud)
?
第二行可能出现什么问题(第一行不会出错)?
使用以下代码时,我对链接器错误感到困惑:
// static_const.cpp -- complete code
#include <vector>
struct Elem {
static const int value = 0;
};
int main(int argc, char *argv[]) {
std::vector<Elem> v(1);
std::vector<Elem>::iterator it;
it = v.begin();
return it->value;
}
Run Code Online (Sandbox Code Playgroud)
但是,这在链接时失败 - 不知何故,它需要有一个静态const"值"的符号.
$ g++ static_const.cpp
/tmp/ccZTyfe7.o: In function `main':
static_const.cpp:(.text+0x8e): undefined reference to `Elem::value'
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
顺便说一句,这与-O1或更好的编译很好; 但对于更复杂的情况,它仍然失败.我使用的是gcc版本4.4.4 20100726(Red Hat 4.4.4-13).
任何想法我的代码可能有什么问题?
注意:我正在使用g ++编译器(我听说这是非常好的,并且应该非常接近标准).
假设您已经声明了一组int:
int a[3] = { 4, 5, 6 };
Run Code Online (Sandbox Code Playgroud)
现在让我们说你真的想要声明对该数组的引用(除了Bjarne说语言支持它之外,没关系为什么).
案例1 - 如果您尝试:
int*& ra = a;
Run Code Online (Sandbox Code Playgroud)
那么编译器就会说:
"invalid initialization of non-const reference of type `int*&' from a temporary of type `int*'"
Run Code Online (Sandbox Code Playgroud)
首先,为什么'a'是一个临时变量(即它在内存中没有位置?)......
无论如何,没问题,每当我看到一个非常量错误时,我会尝试抛出一个const ...
案例2 - 如果您尝试:
int*const&rca = a; //wish I knew where the spaces should go (but my other post asking about this sort of protocol got a negative rank while many of the answers got ranked highly -- aha! there are stupid questions!)
Run Code Online (Sandbox Code Playgroud)
然后一切都很酷,它编译,你得到一个数组的引用. …
在类的标题中,在接口声明之外,我已经声明了全局常量:
NSString * const gotFilePathNotification = @"gotFilePath";
NSString * const gotResultNotification = @"gotResultOfType";
Run Code Online (Sandbox Code Playgroud)
gotResultNotification仅用于此类(尚未),但我在另一个类实现中引用了gotFilePathNotificaion.为此,我导入此标头.
当我尝试编译时,我在此标头中获得了有关gotFilePathNotification的重复符号链接器错误.为什么会这样?
通常,rvalues可以绑定到const引用(const SomeType&).它内置于语言中.但是,std::reference_wrapper<const T>不接受rvalue作为其构造函数参数,因为故意删除了相应的重载.这种不一致的原因是什么?std::reference_wrapper当我们必须传递值但希望保留引用语义时,"广告"作为引用变量的替代.
换句话说,如果const &绑定的右值被认为是安全的,因为它内置于语言中,为什么C++ 11的设计者不允许包含rvalues std::reference_wrapper<const T>?
什么时候会派上用场,你可能会问.例如:
class MyType{};
class Foo {
public:
Foo(const MyType& param){}
};
class MultiFoo {
public:
MultiFoo(std::initializer_list<std::reference_wrapper<const MyType>> params){}
};
int main()
{
Foo foo{MyType{}}; //ok
MultiFoo multiFoo{MyType{}, MyType{}}; //error
}
Run Code Online (Sandbox Code Playgroud) 我以为括号初始化不允许缩小。但是为什么int const允许char括号初始化?
int value1 = 12;
char c1{value1}; // error! no narrowing
const int value2 = 12;
char c2{value2}; // why is this fine?
Run Code Online (Sandbox Code Playgroud)
在Godbolt上看到它。