C++类型强制转换指向常量变量的指针
C++ type casting pointers to constant variables
我希望有一种方法可以为具有大量可访问(但不可编辑)混合类型数据成员的类编写单个 get 函数。如以下代码所示,使用包含成员地址的 void* 强制转换副本的映射将起作用,但是一旦将"const"放入组合中以强制只读,毫不奇怪C++吠叫说"const void*"类型无法重新转换以适当地访问数据成员。以下代码适用于为混合数据类型类编写单个 get 函数,但它有效地使 get 函数访问的所有数据成员公开(具体请参阅memlist
类中的get
函数)。
底线:
有没有办法使指针类型可转换,同时在实际内存位置保持只读?或者更根本地说,是否可以定义指向常量变量的类型可强制转换指针?例如,在我看来,const type *var
为只读变量定义了一个只读/不可铸造的地址,而我正在尝试找到更像type * const var
的东西(到目前为止对我还没有用),尽管我无法找到任何文档。
#include <iostream>
#include <string>
#include <map>
class A{
public:
A(int a, double b): a(a), b(b) {};
private:
int a;
double b;
friend std::ostream& operator<<(std::ostream& os, A& rhs);
};
class memlist{
public:
memlist(int param1, double param2)
{
myint = new int(param1);
mydouble = new double(param2);
myclass = new A(param1,param2);
getMap["myint"] = myint;
getMap["mydouble"] = mydouble;
getMap["myclass"] = myclass;
}
~memlist()
{
delete myint;
delete mydouble;
delete myclass;
}
void* get(std::string param) {return getMap[param];};
private:
int *myint;
double *mydouble;
A *myclass;
std::map<std::string,void*> getMap;
};
std::ostream& operator<<(std::ostream& os, A& rhs){
os << rhs.a << std::endl << rhs.b;
return os;
};
int main(){
int myint = 5;
double mydbl = 3.14159263;
memlist mymem(myint,mydbl);
std::cout << *(int*)mymem.get("myint") << std::endl;
std::cout << *(double*)mymem.get("mydouble") << std::endl;
std::cout << *(A*)mymem.get("myclass") << std::endl;
*(int*)mymem.get("myint") = 10;
std::cout << *(int*)mymem.get("myint") << std::endl;
return 0;
}
输出:
5
3.14159
5
3.14159
10
显示的代码非常,可以说,设计不当。
void*
几乎要摧毁类型系统,因为它进入了C++。如评论中所述,std::any
是更好的解决方案。
也就是说,我认为以类型安全的方式实现您在问题中说明的内容是一个挑战。至少可以说,这是矫枉过正。
#include <iostream>
#include <type_traits>
using namespace std;
template<typename>
struct is_str_literal : false_type {};
template<size_t N>
struct is_str_literal<const char[N]> : true_type {};
template<typename T>
struct is_str_literal<T&> : is_str_literal<T> {};
template<typename T>
constexpr bool is_str_literal_v = is_str_literal<T>::value;
constexpr bool samestr(const char* arr1, const char* arr2, size_t n)
{
return n == 0 ? arr1[0] == arr2[0] :
(arr1[n] == arr2[n]) && samestr(arr1, arr2, n - 1);
}
template<size_t N1, size_t N2>
constexpr bool samestr(const char (&arr1)[N1], const char (&arr2)[N2])
{
return N1 == N2 ? samestr(arr1, arr2, N1 - 1) : false;
}
constexpr char myint[] = "myint";
constexpr char mydouble[] = "mydouble";
constexpr char myclass[] = "myclass";
struct S
{
template<const auto& name>
const auto& get()
{
static_assert(is_str_literal_v<decltype(name)>, "usage: get<var name>()");
if constexpr(samestr(name, ::myint))
return myint;
if constexpr(samestr(name, ::mydouble))
return mydouble;
if constexpr(samestr(name, ::myclass))
return myclass;
}
int myint;
double mydouble;
char myclass;
};
int main()
{
S s;
s.myint = 42;
s.mydouble = 10.0;
s.myclass = 'c';
cout << s.get<myint>() << endl;
cout << s.get<mydouble>() << endl;
cout << s.get<myclass>() << endl;
}
住
这使用 C++17。
经过进一步的探索,我不得不恭敬地不同意评论和答案中先前的评估......自从发布这个问题以来,我在标准 C 库中遇到了许多函数,其中很容易使用 void * 类型(http://www.cplusplus.com/reference/cstdlib/qsort/),更不用说它是依赖于程序员类型转换的 malloc 的返回类型(可能是 C/C++ 中使用最广泛的函数?)。另外,据我所知,std::any 是一个新的 c++17 类,那么 6 个月前你怎么回答这个问题?
- 通过多个头文件使用常量变量
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 非常量变量只读位置的赋值
- 使用大量已知常量变量的正确方法
- 无法在具有常量变量大小的类中创建堆栈分配数组
- 这些语句是否等效(静态变量、常量变量和泛型)
- 包含常量变量并包含在多个文件中的标头的链接错误
- 我们如何修改常量变量的值
- 如何在模板类中设置静态常量变量
- 为什么常量变量是模板特殊化所必需的,而不是常量
- 如何在函数中传递常量变量?
- 定义常量变量的最佳方法
- C++ 声明常量变量,但推迟其初始化?
- 如何初始化具有常量变量的结构数组
- 使用常量变量作为维度将矩阵声明为类成员时出现编译器错误
- 使用指针 c++ 更改常量变量
- c++ 类中的静态常量变量和常量变量在存储方面是否有区别
- 为什么 lambda 对象中的局部变量是常量变量?
- 使用常量变量作为数组的大小
- 为许多类可能需要的所有常量变量制作独立的头文件是否是一种很好的做法?