Динамическая типизация C++

Пользователь

от Hex , в категории: C/C++ , 17 дней назад

Пишу свою реализацию динамической типизации в C++, но хочу вынести реализации перегрузок в отдельный файл, но компиль жалуется, что нет реализации <<. Не могу понять в чём проблема. Помогите пожалуйста.

dynamic.h

```

#pragma once

#include <iostream>

#include <string>


namespace dim {

// обычный print

template<typename T>

void println(const T& value) {

std::cout << std::boolalpha << value << "\n";

}


template<typename T, typename... Args>

void println(const T& value, const Args&... args) {

std::cout << std::boolalpha << value;

println(args...);

}

}


class Dynamic {

public:

Dynamic() : type(VType::Null), int_value(0) {}

Dynamic(int value) : type(VType::Int), int_value(value) {}

Dynamic(double value) : type(VType::Float), float_value(value) {}

Dynamic(const char* value) : type(VType::String), string_value(value) {}

Dynamic(char value) : type(VType::Char), char_value(value) {}

Dynamic(bool value) : type(VType::Bool), bool_value(value) {}


Dynamic& operator=(const int& value) {

type = VType::Int;

int_value = value;

return *this;

}

Dynamic& operator=(const double& value) {

type = VType::Float;

float_value = value;

return *this;

}

Dynamic& operator=(const char* value) {

type = VType::String;

string_value = value;

return *this;

}

Dynamic& operator=(const char& value) {

type = VType::Char;

char_value = value;

return *this;

}

Dynamic& operator=(const bool& value) {

type = VType::Bool;

bool_value = value;

return *this;

}


private:

enum VType { Null, Int, Float, String, Char, Bool };

VType type;

int int_value;

double float_value;

const char* string_value;

char char_value;

bool bool_value;

friend std::ostream& operator<<(std::ostream& os, const Dynamic& dynamic);

friend bool operator<(const Dynamic& lhs, const Dynamic& rhs);

friend bool operator>(const Dynamic& lhs, const Dynamic& rhs);

friend bool operator==(const Dynamic& lhs, const Dynamic& rhs);

friend bool operator!=(const Dynamic& lhs, const Dynamic& rhs);

friend bool operator>=(const Dynamic& lhs, const Dynamic& rhs);

friend bool operator<=(const Dynamic& lhs, const Dynamic& rhs);

friend void operator++(Dynamic& varible);

friend void operator--(Dynamic& varible);

friend Dynamic operator+(const Dynamic& lhs, const Dynamic& rhs);

friend Dynamic operator-(const Dynamic& lhs, const Dynamic& rhs);

friend Dynamic operator/(const Dynamic& lhs, const Dynamic& rhs);

friend Dynamic operator*(const Dynamic& lhs, const Dynamic& rhs);

friend Dynamic operator%(const Dynamic& lhs, const Dynamic& rhs);


};



bool operator<(const Dynamic& lhs, const Dynamic& rhs) {

if (lhs.type == Dynamic::VType::Int && rhs.type == Dynamic::VType::Int) { return lhs.int_value < rhs.int_value; }

if (lhs.type == Dynamic::VType::Float && rhs.type == Dynamic::VType::Float) { return lhs.float_value < rhs.float_value; }

if (lhs.type == Dynamic::VType::Char && rhs.type == Dynamic::VType::Char) { return lhs.char_value < rhs.char_value; }

if (lhs.type == Dynamic::VType::String && rhs.type == Dynamic::VType::String) { return lhs.string_value < rhs.string_value; }

return false;

}

bool operator>(const Dynamic& lhs, const Dynamic& rhs) {

if (lhs.type == Dynamic::VType::Int && rhs.type == Dynamic::VType::Int) { return lhs.int_value > rhs.int_value; }

if (lhs.type == Dynamic::VType::Float && rhs.type == Dynamic::VType::Float) { return lhs.float_value > rhs.float_value; }

if (lhs.type == Dynamic::VType::Char && rhs.type == Dynamic::VType::Char) { return lhs.char_value > rhs.char_value; }

if (lhs.type == Dynamic::VType::String && rhs.type == Dynamic::VType::String) { return lhs.string_value > rhs.string_value; }

return false;

}

bool operator>=(const Dynamic& lhs, const Dynamic& rhs) {

if (lhs.type == Dynamic::VType::Int && rhs.type == Dynamic::VType::Int) { return lhs.int_value >= rhs.int_value; }

if (lhs.type == Dynamic::VType::Float && rhs.type == Dynamic::VType::Float) { return lhs.float_value >= rhs.float_value; }

if (lhs.type == Dynamic::VType::Char && rhs.type == Dynamic::VType::Char) { return lhs.char_value >= rhs.char_value; }

if (lhs.type == Dynamic::VType::String && rhs.type == Dynamic::VType::String) { return lhs.string_value >= rhs.string_value; }

return false;

}

bool operator<=(const Dynamic& lhs, const Dynamic& rhs) {

if (lhs.type == Dynamic::VType::Int && rhs.type == Dynamic::VType::Int) { return lhs.int_value <= rhs.int_value; }

if (lhs.type == Dynamic::VType::Float && rhs.type == Dynamic::VType::Float) { return lhs.float_value <= rhs.float_value; }

if (lhs.type == Dynamic::VType::Char && rhs.type == Dynamic::VType::Char) { return lhs.char_value <= rhs.char_value; }

if (lhs.type == Dynamic::VType::String && rhs.type == Dynamic::VType::String) { return lhs.string_value <= rhs.string_value; }

return false;

}

bool operator==(const Dynamic& lhs, const Dynamic& rhs) {

if (lhs.type == Dynamic::VType::Int && rhs.type == Dynamic::VType::Int) { return lhs.int_value == rhs.int_value; }

if (lhs.type == Dynamic::VType::Float && rhs.type == Dynamic::VType::Float) { return lhs.float_value == rhs.float_value; }

if (lhs.type == Dynamic::VType::Char && rhs.type == Dynamic::VType::Char) { return lhs.char_value == rhs.char_value; }

if (lhs.type == Dynamic::VType::String && rhs.type == Dynamic::VType::String) { return lhs.string_value == rhs.string_value; }

return false;

}

bool operator!=(const Dynamic& lhs, const Dynamic& rhs) {

if (lhs.type == Dynamic::VType::Int && rhs.type == Dynamic::VType::Int) { return lhs.int_value != rhs.int_value; }

if (lhs.type == Dynamic::VType::Float && rhs.type == Dynamic::VType::Float) { return lhs.float_value != rhs.float_value; }

if (lhs.type == Dynamic::VType::Char && rhs.type == Dynamic::VType::Char) { return lhs.char_value != rhs.char_value; }

if (lhs.type == Dynamic::VType::String && rhs.type == Dynamic::VType::String) { return lhs.string_value != rhs.string_value; }

return false;

}

void operator++(Dynamic& varible) {

if (varible.type == Dynamic::VType::Int) { ++varible.int_value; }

if (varible.type == Dynamic::VType::Float) { ++varible.float_value; }

}

void operator--(Dynamic& varible) {

if (varible.type == Dynamic::VType::Int) { --varible.int_value; }

if (varible.type == Dynamic::VType::Float) { --varible.float_value; }

}


Dynamic operator+(const Dynamic& lhs, const Dynamic& rhs){

if (lhs.type == Dynamic::VType::Int && rhs.type == Dynamic::VType::Int) { return lhs.int_value + rhs.int_value; }

if (lhs.type == Dynamic::VType::Float && rhs.type == Dynamic::VType::Float) { return lhs.float_value + rhs.float_value; }

if (lhs.type == Dynamic::VType::String && rhs.type == Dynamic::VType::String) {

char *s = new char[strlen(lhs.string_value)+strlen(rhs.string_value)+1];

std::strcpy(s, lhs.string_value);

std::strcat(s, rhs.string_value);

return s;

}

}


Dynamic operator-(const Dynamic& lhs, const Dynamic& rhs){

if (lhs.type == Dynamic::VType::Int && rhs.type == Dynamic::VType::Int) { return lhs.int_value - rhs.int_value; }

if (lhs.type == Dynamic::VType::Float && rhs.type == Dynamic::VType::Float) { return lhs.float_value - rhs.float_value; }

}


Dynamic operator/(const Dynamic& lhs, const Dynamic& rhs){

if (lhs.type == Dynamic::VType::Int && rhs.type == Dynamic::VType::Int) { return lhs.int_value / rhs.int_value; }

if (lhs.type == Dynamic::VType::Float && rhs.type == Dynamic::VType::Float) { return lhs.float_value / rhs.float_value; }

}


Dynamic operator*(const Dynamic& lhs, const Dynamic& rhs){

if (lhs.type == Dynamic::VType::Int && rhs.type == Dynamic::VType::Int) { return lhs.int_value * rhs.int_value; }

if (lhs.type == Dynamic::VType::Float && rhs.type == Dynamic::VType::Float) { return lhs.float_value * rhs.float_value; }

}


Dynamic operator%(c

onst Dynamic& lhs, const Dynamic& rhs){

if (lhs.type == Dynamic::VType::Int && rhs.type == Dynamic::VType::Int) { return lhs.int_value % rhs.int_value; }

}



```

dynamic.cpp

```

#include "dynamic.h"


std::ostream& Dynamic::operator<<(std::ostream& os, const Dynamic& dynamic) {

switch (dynamic.type) {

case Dynamic::VType::Int:

os << dynamic.int_value;

break;


case Dynamic::VType::Float:

os << dynamic.float_value;

break;


case Dynamic::VType::String:

os << dynamic.string_value;

break;


case Dynamic::VType::Char:

os << dynamic.char_value;

break;


case Dynamic::VType::Bool:

os << (dynamic.bool_value ? "true" : "false");

break;


default:

os << "Uncknown type " << dynamic.type;

break;

}

return os;

}

```

main.cpp

```

#include "dynamic.h"


int main() {

Dynamic a = "Hello ";

Dynamic b = "World";

dim::println(a+b);

return 0;

}

```

Facebook Vk Ok Twitter LinkedIn Telegram Whatsapp

Нет ответов