gpt4 book ai didi

c++ - 动态上下文相关运算符的设计模式(例如模运算)?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:53:03 28 4
gpt4 key购买 nike

关闭。这个问题需要更多 focused .它目前不接受答案。












想改进这个问题?更新问题,使其仅关注一个问题 editing this post .

4年前关闭。




Improve this question




这是我经常遇到的某个软件工程和语言设计问题,我在任何语言中都没有很好的解决方案。我对 C++ 解决方案最感兴趣,但其他(希望是词法范围的)语言的解决方案也值得考虑。
这是一个例子。假设我有一些代码,可能是这样的:

template<class T, class F>
T foo(T a, T b, T c, T d, F func) { return func() / (a * d - b * c); }
我认为来电者 应该 可以使用 foo模运算和正则运算。
换句话说,对于 finite_field 的适当定义,在理想世界中,这 应该 在有限域而不是实数域中评估上面的代码:
int main(int argc, char *argv[])
{
finite_field<int> scoped_field(argc /* let's say this is my modulus */);
return foo(1, 2, 3, 4, []{ return +1; }) + foo(4, 3, 2, 1, []{ return -1; });
}
然而,很明显,这不起作用,因为 foo 内部没有任何内容。 (具体来说,没有一个运算符)知道 scoped_field 施加的算术上下文。 .
我知道的所有解决方案都非常丑陋:
  • 完全停止使用算术运算符。
    使用add(x, y)而不是 x + y , div(x, y)而不是 x / y , 等等。
    然后可能将所有这些放在 Arithmetic 中某种类别并使用this访问当前的“算术上下文”。
    优点:它可以工作,并且不需要存储多余的数据。
    缺点:需要编辑 foo ,这可以说是没有必要的,同时也使它变得不那么令人愉快,并且更难以阅读和写作。
  • 定义自定义 ModInt包装 int 的类型,将模数存储在每个数字中,并重载该类型的运算符以从其中一个输入参数中读取模数。
    优点:它可以工作,并且不需要修改 foo 的正文.
    缺点:效率低且容易出错——每个模数都存储在每个整数中,这意味着在运行时可能会出现冲突错误,以及明显的 O(n) 空间效率低下。更不用说评估上下文不是数字的属性,而是运算符本身的属性。
  • 将“当前上下文”存储在线程局部变量中,并根据上下文重载运算符以使其行为不同。
    优点:它有效(有点)。而且它不浪费空间或需要修改foo .
    缺点:丑陋、可移植性较差、不可重入或容易出错,具体取决于它的实现方式(它会污染被调用者的算术运算符上下文)

  • 所以, 我真的不知道任何可读、可移植和可维护的解决方案 .
    据我所知,似乎我从根本上必须放弃其中之一。

    我的问题:
  • 这是一个常见的问题还是众所周知的问题?
  • 它是否有任何相当流行的语言的优雅解决方案?如果是这样,哪些,以及如何?
  • 可以专门用C++解决吗?是否有某种设计模式或成语?
  • 最佳答案

  • 不。
  • 不知道。尝试标记每一种相当流行的语言。我敢肯定,没有人会遇到问题。
  • 为什么以上帝的名义应该有一个模式或习语来涵盖每个人在语言中可能发现的所有问题?为什么每个解决方案都会突然变成一种模式或成语?不能只是解决问题吗?严重地。

  • 也就是说,对 foo 的小修改可能会产生预期的结果。
    template<typename T, typename F, typename F2>
    T foo(T a, T b, T c, T d, F func, F2 mod) { return func() / (mod(a) * d - mod(b) * c); }

    int main(int argc, char *argv[])
    {
    auto mod = [](int i) { return ModInt(i, modulus); };
    return foo(1, 2, 3, 4, []{ return +1; }, mod) + foo(4, 3, 2, 1, []{ return -1; }, mod);
    }

    由于每次使用 mod使用相同的本地, ModInt 是不可能的有不同的模数。自从 mod仅在运算符优先级等需要它并且任何本地人被破坏并重新使用它们的存储时才被调用,那么我们就是黄金w.r.t.储存空间。 (另外,说真的,堆栈上有几个整数?没什么大不了的。)

    但本质上,模算术是所涉及的运算符的属性。这就是它的定义方式和工作方式。你可以绕过它,但不管你做什么,它至少会有点糟糕。您需要一个用户定义的运算符,但您不能为两种基本类型隐式传递一个用户定义的函数,而且您也不应该能够。

    关于c++ - 动态上下文相关运算符的设计模式(例如模运算)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24933259/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com