簡體   English   中英

在 c++ 中使用運算符重載制作函數式編程語法

[英]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;
}

演示。

我認為您最好堅持標准庫已經提供的內容。

  • 您將重用經過測試的代碼
  • 其他人會發現您的代碼更易於閱讀。
  • 無需讓 C++ 看起來像 python、javascript(或任何其他語言),因為無論如何語言都有完全不同的哲學。

您的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM