Как бы я мог получить значение value
из своей структуры Val
?
#include <iostream>
using namespace std;
template <typename T>
struct Val {
T value;
};
struct node{
void* data;
node* Next;
};
int main() {
node a{};
node b{};
Val<int> c = {41};
Val<string> d = {"gfdsa"};
a.data = &c;
b.data = &d;
a.Next = &b;
cout << (a.Next->data);
}
Это плохой подход. Допустим вы написали так
#include <iostream>
#include <memory>
enum NodeType {String, Int};
struct NodeBase {
NodeType type;
NodeBase* next;
};
template <typename T>
struct Node: NodeBase {
std::unique_ptr<T> data;
};
int main() {
Node<int> a{};
a.data = std::make_unique<int>(41);
a.type = NodeType::Int;
Node<std::string> b{};
b.data = std::make_unique<std::string>("qwerty");
b.type = NodeType::String;
a.next = &b;
...
}
Вам КАЖДЫЙ раз при работе со структурой придётся писать что-то наподобие:
switch(a.next->type) {
case NodeType::Int: {
Node<int>* nodeInt = dynamic_cast<Node<int>*>(a.next);
DoSomethingWithInt(*(nodeInt->data));
break;
}
case NodeType::String: {
Node<std::string>* nodeString = dynamic_cast<Node<std::string>*>(a.next);
DoSomethingWithString(*(nodeString->data));
break;
}
}
А при добавлении нового типа в список вы просто умрёте в поисках всех таких switсh по всему коду.
Поэтому стоит совсем разные объекты хранить отдельно, а похожие наследовать от общей базы:
#include <iostream>
#include <memory>
#include <sstream>
void DoSomethingWithInt(int data) {
std::cout << data << std::endl;
}
void DoSomethingWithString(const std::string& data) {
std::cout << data << std::endl;
}
class NodeValueBase {
public:
virtual void DoSomething() = 0;
virtual void SetData(int value) = 0;
virtual ~NodeValueBase() = default;
};
class NodeValueInt: public virtual NodeValueBase {
public:
NodeValueInt(int value): data(value) {};
virtual void DoSomething() override {
DoSomethingWithInt(data);
}
virtual void SetData(int value) override {
data = value;
}
int data;
};
class NodeValueString: public virtual NodeValueBase {
public:
NodeValueString(const std::string& value): data(value) {};
virtual void DoSomething() override {
DoSomethingWithString(data);
}
virtual void SetData(int value) override {
std::stringstream ss;
ss << value;
data = ss.str();
}
std::string data;
};
template <typename T>
struct Node {
std::unique_ptr<T> data;
Node* next;
};
template<typename D, typename B>
std::unique_ptr<D> static_cast_ptr(std::unique_ptr<B>&& base)
{
return std::unique_ptr<D>(static_cast<D*>(base.release()));
}
int main() {
Node<NodeValueBase> a{};
a.data = static_cast_ptr<NodeValueBase, NodeValueInt>(
std::make_unique<NodeValueInt>(41));
Node<NodeValueBase> b{};
b.data = static_cast_ptr<NodeValueBase, NodeValueString>(
std::make_unique<NodeValueString>("qwerty"));
a.next = &b;
a.next->data->DoSomething();
a.next->data->SetData(123);
a.next->data->DoSomething();
}
Перед тем как "разыменовать" указатель на void, нужно сначала привести тип.
cout << ((Val<string>*)a.Next->data)->value << endl;
И добавь в начале #include<string>
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Вопрос из разряда для начинающих, но учитывая что я под линуксом делаю свой первый проект - думаю это простительно
Пытаюсь из кода на python, распараллеленного с помощью ThreadPoolExecutor вызвать код на C++Создается впечатление, что в момент входа в C++ функцию все питоновские...
Хочу добавить некоторые требования к паролю: