使用运算符重载在 C++ 中创建函数式编程语法
Posted
技术标签:
【中文标题】使用运算符重载在 C++ 中创建函数式编程语法【英文标题】:Make functional programming syntax in c++ with operator overload 【发布时间】:2022-01-18 10:35:21 【问题描述】:#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 ]
我希望在 let
是object
的超类来实现初始化(只是我的第一个想法)。
在object
上还运算符重载[]
和<<
。
但我不知道value
部分。
如果不清楚,value
右侧的任何内容都会放入一个集合中,并带有字符串编号索引(可能是 std::Map ?)。值可以是任何类型(对此也不知道,模板浮现在脑海中)。
任何讨论,资源链接,任何提示。只是想学习 C++ 惊人的可扩展性!
编辑::
关键字value
是必需的。对象也将能够采用这种值 *再次参见代码块示例。一开始没有包括这个,因为这不是我最初的问题。我添加它只是为了强调values
的使用。
【问题讨论】:
object [ values 1, "2", true, -3.14 ];
多维下标运算符仅在C++23中有效。
我正在寻找在 C++ 中创建它。我知道它不标准。使用 c++ 元素,如 typedef, using, templates, operator overload, object orientation etc.
这看起来更像是一个javascript语法,基本上是::std::unordered_map<::std::string, ::std::any>;
【参考方案1】:
你可以使用std::tuple
来存储各种类型并通过重载operator<<
来打印它,并且通过重载C++23 multidimensional subscript 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;
Demo.
【讨论】:
使用 let 和你的操作符 [] 很好。【参考方案2】:我认为你最好坚持标准库已经提供的内容。
您将重复使用经过测试的代码 其他人会发现您的代码更易于阅读。 无需让 C++ 看起来像 python、javascript(或任何其他语言),因为无论如何语言都有完全不同的哲学。您的对象可以由 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;
【讨论】:
以上是关于使用运算符重载在 C++ 中创建函数式编程语法的主要内容,如果未能解决你的问题,请参考以下文章