有些语言,如Haskell,不区分传值和传递引用.然后,编译器可以使用启发式近似地选择最有效的调用约定.一个启发式示例是针对Linux x64 ABI:如果参数的大小大于16个字节,则将指针传递给堆栈,否则传递寄存器中的值.
在Rust中同时保留传值和传递引用(当然不可变)的概念有什么好处,并迫使用户选择?
可能是这样的情况,如果看到值被修改,那么pass-by-value是pass-by-reference + copy的语法糖?
我正在研究单例类型可以在多大程度上模拟依赖类型,并且我遇到了一个问题.最小的代码我复制错误:
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeInType #-}
import Data.Kind(Type)
data SBool :: Bool -> Type where
STrue :: SBool 'True
SFalse :: SBool 'False
data SSBool :: SBool b -> Type where
SSFalse :: SSBool 'SFalse
SSTrue :: SSBool 'STrue
Run Code Online (Sandbox Code Playgroud)
错误消息是:
期待的'SBool b',但是''SFalse'有点'SBool'False'
haskell higher-kinded-types dependent-type singleton-type data-kinds
template <class T>
T Read () {
T t;
cin >> t;
if (cin.fail()) {
// ...
}
return t;
}
Run Code Online (Sandbox Code Playgroud)
此通用代码读取类型为T的值,并带有一些额外的错误处理.它依赖于具有可以解析T的operator >>,并且以这种方式它可以扩展到新类型.
我没有意识到它依赖于T有一个默认的构造函数.现在我遇到了这个问题.
我有什么选择?
做正确的方法是什么?
我有一个struct/class,它是partiall Plain Old Data(POD).
struct S {
// plain-old-data structs with only arrays and members of basic types (no pointers);
Pod1 pod1;
Pod2 pod2;
Pod3 pod3;
Pod4 pod4;
vector<int> more;
};
Run Code Online (Sandbox Code Playgroud)
我很多时候复制了S类的对象.我想用memcpy复制它,但S :: more阻止了它.我想避免调用4个memcpy,并将其全部用于一个额外的性能.我应该这样做吗?
memcpy(s1, s2, sizeof(Pod1) + sizeof(Pod2) + sizeof(Pod3) + sizeof(Pod4);
Run Code Online (Sandbox Code Playgroud)
我不能将它们打包在单独的结构中,因为它会破坏使用pod1-pod4的所有代码.
什么是最好的解决方案?
假设我有一个只有一个构造函数的类:
class T {
public:
T(BigClass&& big) : big(std::move(big)) {}
...
SomeBigClass
};
Run Code Online (Sandbox Code Playgroud)
在大多数地方,构造函数在temporaries上调用,但在一个地方我需要制作BigClass的显式副本,因为它不是临时的,并且将在循环中多次使用:
void foo(const BigClass& big) {
while (...) {
T t(std::make_a_copy(big));
...
}
}
Run Code Online (Sandbox Code Playgroud)
std::move在C++ 11或C++ 14中是否有任何"双重"功能可以取代上面的make_a_copy?
编辑:一些澄清.
示例第一:
template <class HashingSolution>
struct State : public HashingSolution {
void Update(int idx, int val) {
UpdateHash(idx, val);
}
int GetState(int idx) {
return ...;
}
};
struct DummyHashingSolution {
void UpdateHash(int idx, int val) {}
void RecalcHash() {}
};
struct MyHashingSolution {
void UpdateHash(int idx, int val) {
...
}
void RecalcHash() {
...
UpdateHash(idx, GetState(idx)); // Problem: no acces to GetState function, can't do recursive application of templates
...
}
};
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我可以将MyHashingSolution传递给State类,因此State可以访问HashingSolution的方法,但是HashingSolution不能调用GetState.有可能解决这个问题吗?
这是最深的循环.这里的虚拟功能使性能下降超过25%.内联对我来说至关重要.
我使用宏来编码这样的展开循环:(愚蠢的例子)
#define foreach_small_prime(p, instr) { \
int p; \
p = 2; instr; \
p = 3; instr; \
p = 5; instr; \
p = 7; instr; \
}
foreach_small_prime(pp, cout << pp);
int sum = 0;
foreach_small_prime(pp, {
sum += pp;
if (sum >= 10) cout << sum << endl;
});
Run Code Online (Sandbox Code Playgroud)
但在某些情况下,我可能会用于构造:
#define foreach_small_even(ii) for(int ii = 0; ii < 20; ii += 2)
int sum = 0;
foreach_small_even(pp) {
sum += pp;
if (sum >= 10) cout …Run Code Online (Sandbox Code Playgroud) 这是我正在研究的示例程序,用于读取每行一个值列表的文件.我必须添加所有这些值转换为double,还需要对值进行排序.这是我到目前为止所做的,它工作正常.
import scala.io.Source
object Expense{
def main(args: Array[String]): Unit = {
val lines = Source.fromFile("c://exp.txt").getLines()
val sum: Double = lines.foldLeft(0.0)((i, s) => i + s.replaceAll(",","").toDouble)
println("Total => " + sum)
println((Source.fromFile("c://exp.txt").getLines() map (_.replaceAll(",", "").toDouble)).toList.sorted)
}
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是,你可以看到我正在读取文件两次,我想避免它.由于它Source.fromFile("c://exp.txt").getLines()给你一个迭代器,我只能循环它一次,然后下一个操作它将为null,所以我不能再次重复使用它lines进行排序,我需要再次从文件中读取.另外,我不想将它们存储到临时列表中.是否有任何优雅的方式以功能的方式这样做?
为什么这段代码会破坏Scala 2.8.1编译器?
val a = new Array[{ var x = 1 }](3)
Run Code Online (Sandbox Code Playgroud)
这是编译器错误吗?
无论如何它是一个合法的Scala代码?(我想要一个具有匿名类类型的对象数组)
更新:
我想要的是:
class X { var x = 1}
val a = new Array[X](3)
Run Code Online (Sandbox Code Playgroud)
但无需定义独立的X.