[英]Make functional programming syntax in c++ with operator overload
#include <MySyntax.hpp>
...
//let name1 = object;
//
//let name2 = object[ othervar1 , othervar2 , values val1, val2, val3... ];
let o3 = object [ values 1, "2", true, -3.14 ];
std::cout << o3; // prints: object [ “0”:1 , “1”:“2” , “2”:true , “3”:-3.14 ]
我希望在 <MySyntax.hpp> 中使用 c++11 進行此操作。 我正在考慮let
成為object
的超類來實現初始化(只是我的第一個想法)。 還運算符重載object
上的[]
和<<
。 但我不知道的是value
部分。 如果不清楚,則將value
右側的任何內容放入集合中,並帶有字符串編號索引(可能是std::Map?)。 值可以是任何類型(對此也不知道,模板浮現在腦海中)。 任何討論,資源鏈接,任何提示。 只是想學習 C++ 驚人的可擴展性!
編輯:: 關鍵字value
是必需的。 Object 也將能夠采用這種值 *再次參見代碼塊示例。 一開始沒有包括這個,因為這不是我最初的問題。 我添加它只是為了強調values
的使用。
您可以使用std::tuple
存儲各種類型並通過重載operator<<
來打印它,並通過重載 C++23 多維下標 operator來支持此語法。
像這樣的東西:
#include<tuple>
#include<iostream>
template<class... Args>
using let = std::tuple<Args...>;
struct {
template<class... Args>
constexpr auto operator[](Args&&... args) const {
return std::tuple(std::forward<Args>(args)...);
}
} object;
template<class... Args>
auto& operator<<(std::ostream& os, const std::tuple<Args...>& t) {
return std::apply([&os, i = 0](auto& first, auto&... rest) mutable -> auto& {
os << std::boolalpha << "[" << i++ << ":" << first;
((os << ", " << i++ << ":" << rest), ...);
return os << "]";
}, t);
}
int main() {
let o = object[1, "2", true, -3.14];
std::cout << o;
}
我認為您最好堅持標准庫已經提供的內容。
您的 object 可以用 std::tuple 表示,然后代碼將變為:
#include <iostream>
#include <string_view>
#include <tuple>
//-------------------------------------------------------------------------------------------------
// MySyntax.hpp
// helper function to put a heteroganous list of types into one datastructure
template<typename... args_t>
auto object(args_t&&... args)
{
std::tuple<args_t...> obj{ std::forward<args_t>(args)... };
return obj;
}
// convert function for pretty printing
// normally convert to output type does nothing
template<typename type_t>
const type_t& convert(const type_t& value)
{
return value;
}
// booleans should be outputed as text
std::string_view convert(const bool value)
{
return value ? "true" : "false";
}
// output a tuple to stream
template<class type_t, size_t... index>
void output(std::ostream& os, const type_t& object, std::index_sequence<index...>)
{
os << "[";
// fold expression (so there is no need to create a recursive template function)
(..., (os << (index == 0 ? "" : ", ") << "\"" << index << "\":" << convert(std::get<index>(object))));
os << "]\n";
}
// overload stream operator for tuples
template<typename... args_t>
std::ostream& operator<<(std::ostream& os, const std::tuple<args_t...>& object)
{
output(os, object, std::make_index_sequence<sizeof...(args_t)>());
return os;
}
//-------------------------------------------------------------------------------------------------
// #include <MySyntax.hpp>
int main()
{
// use auto instead of let
auto o3 = object(1, 2.0, true, "hello");
std::cout << "object " << o3;
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.