标签: mutable

正确替代c ++中的"可变函数"

在c ++中的类中包装算法时,我经常遇到const正确性的问题.我觉得我想要一个可变功能,虽然这是不允许的.任何人都可以建议我如何实现如下的类?

以下是我编写的代码.

  • 函数run()不应该是const函数,因为它会更改数据.
  • 函数get_result()应该是一个常量函数(就用户而言),因为它返回数据.

但是,如果用户在不调用run()的情况下请求结果,我希望get_result()函数运行算法.这打破了const的正确性,因为我有一个const函数调用非const函数.

class operate_on_data
{
  std::vector<double> m_data;  // the data to modify
  bool m_completed;  // check to see if the function run() has been called
public:
  operate_on_data(std::vector<double> data)
    : m_data(data), m_completed(false) {}  //initialise
  void run() //I don't want this function to be const  
  {
    //The algorithm goes here - it alters m_data.
    m_completed = true;  //the algorithm has been run
  }
  std::vector<double> get_result() const //I want this function to be const
  {
    /*The following …
Run Code Online (Sandbox Code Playgroud)

c++ mutable

14
推荐指数
2
解决办法
1万
查看次数

在C++中将参数传递给lambda

我似乎错过了C++中lambda机制的一些观点.这是代码:

std::vector<int> vec (5);

int init = 0;
std::generate(begin(vec), end(vec), [init]() mutable { return ++init; });

for (auto item : vec) {
    std::cout << item << " ";
}
std::cout << std::endl << init << std::endl;
Run Code Online (Sandbox Code Playgroud)

如果没有mutable它就不会编译,因为我正在改变initlambda.
现在,我的理解拉姆达被每一个信息载体的一个项目新的全新副本init是0,所以,1必须每次都返回.但这段代码的输出是:
1 2 3 4 5
0

它看起来像在执行开始时generate复制init 一次.但为什么?它应该像这样工作吗?

c++ parameters lambda mutable

14
推荐指数
3
解决办法
1万
查看次数

D中的逻辑常量

D有两种类型的const:不可变变量是声明为不可变的变量,并且总是不可变的,而const变量只是对象的只读版本.

逻辑const是将函数标记为const,但允许对一个或多个成员变量进行写访问.这种方法的典型用途是进行惰性评估,例如(在C++中)

struct Matrix
{
  double determinant() const
  {
    if ( m_dirty )
    {
      m_determinant = /* expensive calculation */;
      m_dirty = false;
    }
    return m_determinant;
  }

  void set(int i, int j, double x) { m_dirty = true; ...; }

  mutable bool m_dirty;
  mutable double m_determinant;
};
Run Code Online (Sandbox Code Playgroud)

在这里,determinant()const,但仍然可以修改m_dirty,m_determinant因为它们被标记为mutable.

d常量(FAQ)说,D2不支持,因为它提供了,这是造成障碍编写并发程序,并使得一定的优化更加困难弱势保证逻辑常量.

我完全理解这个问题,但是如果我们需要逻辑const呢?

考虑上面的情况与Matrix类,但没有缓存(和任何需要逻辑const).还想象一下,这个类在我的代码库中使用,并且主要通过const引用访问.

现在考虑分析已经揭示该determinant()函数是代码中的瓶颈,而且它通常被重复访问,其值很少改变,即如上所述的缓存将是完美的优化.

没有逻辑const我怎么能这样做呢?遍及我的代码库将const引用更改为非const引用不是一种选择(出于显而易见的原因). …

d const const-correctness mutable

13
推荐指数
1
解决办法
1704
查看次数

无法附加到scala的可变LinkedList?

我正在查看API,并且:+方法返回一个新的LinkedList.append方法只允许附加另一个链表.+ =方法需要var才能工作.如果LinkedList是可变的,为什么有人会需要这些?这有什么疯狂的?

如果我在Java中有这样的东西

final LinkedList myList = new LinkedList<String>();
mylist.add("balh");
Run Code Online (Sandbox Code Playgroud)

如何在Scala中实现相同的功能?

scala mutable scala-collections

13
推荐指数
2
解决办法
5470
查看次数

如何将可变HashMap转换为Scala中的不可变等效项?

在我的函数内部,我通过用数据填充新的可变HashMap来构造结果集(如果有更好的方法 - 我很感激评论).然后我想将结果集作为不可变的HashMap返回.如何从变量中导出一个不可变的?

scala mutable immutability scala-collections

13
推荐指数
2
解决办法
1万
查看次数

修改就地并返回副本是否有意义?

注意:我正在标记这个Python和C++,因为我已经看到了两者中的例子,但问题是语言无关.

修改对象的函数或类方法有两种选择:直接在相关对象中修改数据,或创建新副本并在保持原始状态不变的情况下返回它.通常,您可以通过查看函数返回的内容来判断哪个是哪个.

有时,您会找到一个尝试同时执行这两项操作的函数,修改原始对象,然后返回该对象的副本或引用.有没有一种情况比只做一个或另一个提供任何优势?

我已经看到了Fluent InterfaceMethod Chaining的例子,它依赖于返回对象的引用,但这似乎是一个在上下文中应该很明显的特殊情况.

我的第一个坏例子直接来自Python文档,并说明了可变默认参数的问题.对我来说,这个例子是不现实的:如果函数修改了它的参数,那么有一个默认值是没有意义的,如果它返回一个副本,那么应该在进行任何修改之前进行复制.这个问题只存在,因为它试图同时做到这两点.

def f(a, L=[]):
    L.append(a)
    return L
Run Code Online (Sandbox Code Playgroud)

第二个例子来自CStringT::MakeUpper函数中的Microsoft C++ .文档说明了返回值:

返回字符串的副本,但全部为大写字符.

这导致人们期望原件保持不变.问题的一部分是文档有误导性,如果你看原型,你会发现它正在返回对字符串的引用.除非仔细观察,否则您不会注意到这一点,并将结果分配给新字符串进行编译而没有错误.后来出人意料.

c++ python mutable

13
推荐指数
1
解决办法
366
查看次数

我可以空基优化可变数据吗?

我有一个类模板,看起来像这样:

template<typename T, typename Mutex, typename SomePolicy>
class my_class {
public:
  T f() const {
    resource_lock a_lock(some_mutex);
    return some_policy.some_operation(some_data);
  }
private:
  T             some_data;
  mutable Mutex some_mutex;
  SomePolicy    some_policy;
};
Run Code Online (Sandbox Code Playgroud)

如果不同时使用,我们有一个虚拟互斥类型,它具有所有成员函数作为内联空函数而没有数据.有些策略包含每个实例数据和那些没有任何数据的策略.

这是库代码,事实证明这个类模板在应用程序代码中使用,其中额外的字节对于数据成员是必需的some_mutex,some_policy甚至当它们是空类时.所以我想利用空基优化.对于该政策,这很容易:

template<typename T, typename Mutex, typename SomePolicy>
class my_class {
public:
  T f() const {
    resource_lock a_lock(the_data.some_mutex);
    return the_data.some_operation(the_data.some_data);
  }
private:
  struct data : SomePolicy {
    T             some_data;
    mutable Mutex some_mutex;
  };
  data the_data;
};
Run Code Online (Sandbox Code Playgroud)

但是,考虑到这some_mutex一点mutable,我不知道如何使它成为一个没有制作的基类the_data,因此所有数据mutable,从而完全接管编译器的责任,保护我免受愚蠢的常量错误. …

c++ optimization mutable

13
推荐指数
2
解决办法
363
查看次数

如何将字典条目的值声明为可变?

Google提供了大量在F#字典(或其他集合)中添加和删除条目的示例.但我没有看到相当于的例子

myDict["Key"] = MyValue;
Run Code Online (Sandbox Code Playgroud)

我试过了

myDict.["Key"] <- MyValue
Run Code Online (Sandbox Code Playgroud)

我也试图将词典声明为

Dictionary<string, mutable string>
Run Code Online (Sandbox Code Playgroud)

以及这方面的几个变种.然而,我都打不上的正确组合,但...如果它实际上可能在F#.

编辑:违规代码是:

type Config(?fileName : string) =
    let fileName = defaultArg fileName @"C:\path\myConfigs.ini"

    static let settings =
        dict[ "Setting1", "1";
              "Setting2", "2";
              "Debug",    "0";
              "State",    "Disarray";]

    let settingRegex = new Regex(@"\s*(?<key>([^;#=]*[^;#= ]))\s*=\s*(?<value>([^;#]*[^;# ]))")

    do  File.ReadAllLines(fileName)
        |> Seq.map(fun line -> settingRegex.Match(line))
        |> Seq.filter(fun mtch -> mtch.Success)
        |> Seq.iter(fun mtch -> settings.[mtch.Groups.Item("key").Value] <- mtch.Groups.Item("value").Value)
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

System.NotSupportedException: This value may not be mutated
   at Microsoft.FSharp.Core.ExtraTopLevelOperators.dict@37-2.set_Item(K key, V value)
   at …
Run Code Online (Sandbox Code Playgroud)

f# dictionary mutable

12
推荐指数
2
解决办法
1万
查看次数

可变类作为不可变类的子类

我希望有这样的不可变Java对象(强烈简化):

class Immutable {

    protected String name;

    public Immutable(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

}
Run Code Online (Sandbox Code Playgroud)

在某些情况下,对象不仅应该是可读的而且是可变的,因此我可以通过继承添加可变性:

public class Mutable extends Immutable {

    public Mutable(String name) {
        super(name);
    }

    public void setName(String name) {
        super.name = name;
    }

}
Run Code Online (Sandbox Code Playgroud)

虽然这在技术上很好,我想知道它是否符合OOP和继承,mutable也是类型不可变的.我想避免OOP犯罪抛出UnsupportedOperationException不可变对象,就像Java集合API那样.

你怎么看?还有其他想法吗?

java oop inheritance mutable immutability

12
推荐指数
3
解决办法
3964
查看次数

类和结构闭包中的Swift可变结构表现不同

我有一个类(A),它有一个struct变量(S).在这个类的一个函数中,我在struct变量上调用一个mutating函数,这个函数需要一个闭包.此闭包的主体检查struct变量的name属性.

结构的变异函数依次调用某个类(B)的函数.这个类的函数再次关闭.在这个闭包的主体中改变结构,即更改name属性,并调用第一个类提供的闭包.

当我们检查struct的name属性时调用第一个类(A)闭包时,它永远不会被更改.

但是在第2步中,如果我使用结构(C)而不是类B,我会看到内部类A的闭包结构实际上已经改变了.以下是代码:

class NetworkingClass {
  func fetchDataOverNetwork(completion:()->()) {
    // Fetch Data from netwrok and finally call the closure
    completion()
  }
}

struct NetworkingStruct {
  func fetchDataOverNetwork(completion:()->()) {
    // Fetch Data from netwrok and finally call the closure
    completion()
  }
}

struct ViewModelStruct {

  /// Initial value
  var data: String = "A"

  /// Mutate itself in a closure called from a struct
  mutating func changeFromStruct(completion:()->()) {
    let networkingStruct = NetworkingStruct()
    networkingStruct.fetchDataOverNetwork {
      self.data = "B"
      completion()
    }
  } …
Run Code Online (Sandbox Code Playgroud)

mutable mvvm ios swift swift-structs

11
推荐指数
1
解决办法
3673
查看次数