如果类 A 修改其构造参数,我可以使用常量参数初始化 const A 吗?
If class A modifies its construction parameters, can I initialize const A's with const parameters?
假设我有
class A final {
int& ir;
public:
A(int& x) : ir(x) { }
void set(int y) { ir = y; } // non-const method!
int get() const { return ir; }
};
和
const int i;
显然我不能有
A a(i);
因为那会破坏恒常性。但我也不能有
const A a(i);
尽管事实上这不会破坏恒常性。C++不支持"仅恒量"的 ctors,例如,在这种情况下,需要const int&
.有没有办法const A a
包装对i
的引用 - 除了
A a(const_cast<int &>(i))
?
"Const" 表示对象在构造函数结束和析构函数开始之间是恒定的(在构造期间,您必须能够更改对象)。C++没有常量对象首选的"准备构造函数"。
您可以通过应用 boost::variant
来尝试此解决方法。这在编译时不是完全类型安全的,但至少通过引发异常在运行时检测错误。
#include <boost/variant.hpp>
#include <iostream>
class R {
boost::variant<int&, const int&> v;
public:
R(int&v):v(v) { }
R(const int&v):v(v) { }
// works with both
int get() const {
return boost::apply_visitor(
[](int x){return x;}, v);
}
// only works for non-const A. If at construction, a const
// int was passed, throws an error at runtime
void set(int x) {
boost::get<int&>(v) = x;
}
};
int main() {
int a = 0;
const int b = a;
R r1(a);
R r2(b);
const R r3(a);
std::cout << r1.get() << r2.get() << r3.get();
// r3.set(1); // compile error
r1.set(1); // works
r2.set(1); // runtime error
}
>C++没有完全常量类的概念,如果引用int &
仅用作const int &
,编译器可能不会执行。所以基本上,你不能这样做。
这
很奇怪,但是
class A final {
union{
int& ir;
const int ○
};
public:
A(int& x) : ir(x) { }
A(const int& x) : cir(x) { }
void set(int y) { ir = y; } // non-const method!
int get() const { return ir; }
};
int main(int argc, char *argv[])
{
const int cv = 8;
int v = 6;
A a( cv );
std::cout << a.get() << std::endl;
a.set( v );
std::cout << a.get() << std::endl;
return 0;
}
此外,您的set和get方法在值而不是引用上起作用,因此看起来您做错了什么
这不是我编写代码的方式,但它以某种方式工作。如果从 const 变量构造模板类,则 set() 函数也会定义 const,并且不会更改状态。通过从非常量变量构造,set 函数能够更改状态。
#include <iostream>
#include <string>
#include <type_traits>
template<typename T>
class A
{
T &_i;
public:
A(T &i) : _i(i) {}
template <typename D = T,
typename = std::enable_if_t<std::is_const<D>::value
>
>
void set(T i) const { std::cout << "Do nothing on set" << std::endl; }
template <typename D = T,
typename = std::enable_if_t<!std::is_const<D>::value>
>
void set(T i) { std::cout << "Do something on set" << std::endl; }
};
int main()
{
{
std::cout << "Construct from NON const variable" << std::endl;
int b = 5;
A<decltype(b)> a(b);
a.set(3);
}
{
std::cout << "Construct from const variable" << std::endl;
int const b = 5;
A<decltype(b)> a(b);
a.set(3);
}
}
这将打印:
Construct from NON const variable
Do something on set
Construct from const variable
Do nothing on set
class A {
const int& ir; // <<-- it's a const int.
/* ... */
public:
A(int& x) : ir(x) { }
};
相关文章:
- 如何创建长度由常量参数指定的数组
- 通过常量引用传递参数的矩阵模板类
- 具有常量引用参数的函数模板专用化
- 使用自动推导的 lambda 参数作为常量表达式
- C++:常量引用参数
- 常量参数"real"常量吗?
- 常量参数存储在哪里 (C++)?
- 常量函数,当其参数是对文字类型的引用时
- 区分接受常量参数的函数引用/指针和与函数参数同名的非常量参数
- 必须非常量别名参数及其默认参数常量
- 字符串参数常量字符* 和常量 wchar_t*
- 可选参数常量引用重新分配
- 推导模板化类参数的模板参数:常量问题
- 从函数参数常量字符串 (&) 设置值
- 为什么我必须声明这些引用参数常量或按值传递
- C++使用一个参数常量重载
- 如果要执行const_cast,为什么要制作参数常量?
- 模板非类型参数常量限制筛选器库
- 标记方法指针/引用参数常量真的会显著影响性能吗
- 当函数参数常量引用 T 时,为什么 T 的模板参数推导'skips'数组元素的恒定性?