你走多远const
?您是否只是const
在必要时制作功能,或者您是否全力以赴并在任何地方使用它?例如,想象一个简单的mutator,它接受一个布尔参数:
void SetValue(const bool b) { my_val_ = b; }
Run Code Online (Sandbox Code Playgroud)
这const
实际上有用吗?我个人选择广泛使用它,包括参数,但在这种情况下,我想知道它是否值得?
我还惊讶地发现你可以省略const
函数声明中的参数,但可以将它包含在函数定义中,例如:
.h文件
void func(int n, long l);
Run Code Online (Sandbox Code Playgroud)
.cpp文件
void func(const int n, const long l)
Run Code Online (Sandbox Code Playgroud)
是否有一个原因?这对我来说似乎有点不寻常.
我注意到可以const
在函数声明中出现值参数的限定符,然后在定义中省略.这不会改变函数的签名.它实际上编译得很好.
我还注意到常规类和模板类之间的行为是不同的.GCC和Clang的处理方式也有区别.
请考虑以下代码:
template <typename T> struct A {
void f(const int);
};
template <typename T> void A<T>::f(int x) {
x = 0;
}
struct B {
void f(const int);
};
void B::f(int x) {
x = 0;
}
void f() {
A<float> a;
a.f(0);
B b;
b.f(0);
}
Run Code Online (Sandbox Code Playgroud)
当我使用GCC编译时,我没有错误.有了Clang我得到:
test.cpp:10:7: error: read-only variable is not assignable
x = 0;
~ ^
test.cpp:26:7: note: in instantiation of member function 'A<float>::f' requested here
a.f(0);
^
Run Code Online (Sandbox Code Playgroud)
海湾合作委员会在定义中优先考虑限定词.Clang使用了声明,仅用于模板类A
.
我的问题是: …
这是我先前问题的延续.请注意,声明void (*pf)(int) = bar;
会触发static_assert
.我不明白为什么.另请注意,如果我在此声明中替换bar
,bar<const int>
则代码将进行编译.
#include <iostream>
#include <type_traits>
template<typename T>
void bar(T t)
{
static_assert(std::is_same<T, const int>::value, "Error!");
std::cout << t << '\n';
}
int main()
{
// static_assert doesn't fire because T==const int
bar<const int>(1);
// But here static_assert fires because T==int (see the error message). Why is this?
// If I replace `bar` by `bar<const int>` below the code compiles.
void(*pf)(int) = bar;
pf(1000);
}
Run Code Online (Sandbox Code Playgroud)