我想听听那些已经熟练掌握F#(以及一般的函数式编程)的人们,从现在开始我应该成为一名更好/专业的F#程序员?
我已经了解了很多F#语法,并且拥有多年的C++经验.我的目标是,作为工程师和数学家,设计更好的科学库(线性代数包,偏微分求解器等).
doxygen版本1.8.2 的更改日志表示已向C++ 11尾随返回类型添加了支持.但是,使用doxygen版本1.8.4解析我的代码会导致返回类型auto
而不是尾随返回类型.
是否需要设置任何选项才能使其正常工作?
编辑:
在下图中可以看出,返回类型是auto
,我认为,这不是正确的行为.
c++ doxygen c++11 trailing-return-type return-type-deduction
假设以下代码:
#include <iostream>
template<typename T>
struct Link
{
Link(T&& val) : val(std::forward<T>(val)) {}
T val;
};
template<typename T>
std::ostream& operator<<(std::ostream& out, const Link<T>& link)
{
out << "Link(" << link.val << ")";
return out;
}
template<typename T>
auto MakeLink(T&& val) -> Link<T>
{
return {std::forward<T>(val)};
}
namespace Utils {
template<typename Any>
constexpr auto RemoveLinks(const Any& any) -> const Any&
{
return any;
}
template<typename T>
constexpr auto RemoveLinks(const Link<T>& link) -> decltype(RemoveLinks(link.val))
{
return RemoveLinks(link.val);
}
} /* Utils */ …
Run Code Online (Sandbox Code Playgroud) 给定一个表达式模板树,我想在处理它之前创建一个新的优化树.请考虑以下乘法运算示例:
a * b * c * d,
Run Code Online (Sandbox Code Playgroud)
由于operator*
表达式树的从左到右的相关性,它产生:
(((a * b) * c) * d).
Run Code Online (Sandbox Code Playgroud)
我想生成一个转换的表达式树,其中乘法从右到左发生:
(a * (b * (c * d))).
Run Code Online (Sandbox Code Playgroud)
考虑二进制表达式类型:
template<typename Left, typename Right>
struct BinaryTimesExpr
{
BinaryTimesExpr() = default;
BinaryTimesExpr(const BinaryTimesExpr&) = default;
BinaryTimesExpr(BinaryTimesExpr&&) = default;
BinaryTimesExpr(Left&& l, Right&& r) : left(forward<Left>(l)), right(forward<Right>(r)) {}
BinaryTimesExpr& operator=(const BinaryTimesExpr&) = default;
BinaryTimesExpr& operator=(BinaryTimesExpr&&) = default;
Left left;
Right right;
};
Run Code Online (Sandbox Code Playgroud)
定义乘法运算符operator*
:
template<typename Left, typename Right>
BinaryTimesExpr<Constify<Left>, Constify<Right>> operator*(Left&& l, Right&& r)
{ …
Run Code Online (Sandbox Code Playgroud) 考虑界面:
type IVector =
abstract Item : int -> float
Run Code Online (Sandbox Code Playgroud)
现在,让我们定义类:
type DenseVector(size : int) =
let mutable data = Array.zeroCreate size
interface IVector with
member this.Item with get n = data.[n]
Run Code Online (Sandbox Code Playgroud)
如何提供一种方法来改变密集向量的第n个条目?然后,将上面的代码修改为:
type DenseVector(size : int) =
let mutable data = Array.zeroCreate size
interface IVector with
member this.Item with get n = data.[n]
and set n value = data.[n] <- value
Run Code Online (Sandbox Code Playgroud)
不过,我得到,因为抽象方法的签名下面的错误Item
的IVector
界面:
未找到与此覆盖对应的抽象属性.
那么,究竟应该是签名Item
的IVector
?
我的机器上安装了GDB 7.5.看起来漂亮的STL打印机已经捆绑了这个版本,因为运行:
(gdb) info pretty-printers
Run Code Online (Sandbox Code Playgroud)
打印所有可用STL打印机的长列表.
调试用g ++编译的C++代码可以获得漂亮打印的正确行为.但是,如果使用clang ++编译相同的代码,则不会出现相同的情况.
下面是我run
gdb 时的输出:
BFD: /usr/lib/libstdc++.6.dylib(i386:x86-64): unknown load command 0x2a
BFD: /usr/lib/libstdc++.6.dylib(i386:x86-64): unknown load command 0x2b
BFD: /usr/lib/libSystem.B.dylib(i386:x86-64): unknown load command 0x2a
BFD: /usr/lib/libSystem.B.dylib(i386:x86-64): unknown load command 0x2b
BFD: /usr/lib/libc++abi.dylib(i386:x86-64): unknown load command 0x2a
BFD: /usr/lib/libc++abi.dylib(i386:x86-64): unknown load command 0x2b
BFD: /usr/lib/system/libcache.dylib(i386:x86-64): unknown load command 0x2a
BFD: /usr/lib/system/libcache.dylib(i386:x86-64): unknown load command 0x2b
BFD: /usr/lib/system/libcommonCrypto.dylib(i386:x86-64): unknown load command 0x2a
BFD: /usr/lib/system/libcommonCrypto.dylib(i386:x86-64): unknown load command 0x2b
BFD: /usr/lib/system/libcompiler_rt.dylib(i386:x86-64): unknown load command 0x2a
BFD: …
Run Code Online (Sandbox Code Playgroud) 给定一个指向函数对象的指针:
std::shared_ptr<std::function<double(double)>> f;
Run Code Online (Sandbox Code Playgroud)
在C++ 11中是否有一个内置的构造允许在std::bind
语句中使用这个指针?例如:
std::function<double()> g = std::bind(built_in(f), 0.0);
Run Code Online (Sandbox Code Playgroud)
我正在做的是使用variadic模板:
template<typename Ret, typename... Args>
std::function<Ret(Args...)> get_fn(const std::shared_ptr<std::function<Ret(Args...)>>& f)
{
return [=](Args... args) -> Ret { return (*f)(args...); };
}
Run Code Online (Sandbox Code Playgroud)
这允许我写:
std::function<double()> g = std::bind(get_fn(f), 0.0);
Run Code Online (Sandbox Code Playgroud)
提前致谢.
编辑:我应该更清楚.我需要在共享指针内使用函数对象的实例以进行优化.
假设我有一系列支持给定成员函数的类型,如Property
下面的成员:
type FooA = {...} with
member this.Property = ...
type FooB = {...} with
member this.Property = ...
Run Code Online (Sandbox Code Playgroud)
假设成员Property为上述每种类型返回一个整数.现在,我想编写一个可以执行以下操作的通用函数:
let sum (a: 'T) (b: 'U) = a.Property + b.Property
Run Code Online (Sandbox Code Playgroud)
我习惯用C++编写以下代码:
template<typename T, typename U>
int sum(T a, U b)
{
return a.Property + b.Property;
}
Run Code Online (Sandbox Code Playgroud)
如何在F#中实现等效的实现?
假设我有一个计算器类,使用std::function
如下对象实现策略模式(请参阅Scott Meyers,Effective C++:55改进程序和设计的具体方法):
class Calculator
{
public:
...
std::vector<double> Calculate(double x, double y)
{
std::vector<double> res;
for(const Function& f : functions)
res.push_back(f(x,y));
return res;
}
private:
std::vector<Function> functions;
};
Run Code Online (Sandbox Code Playgroud)
哪里
typedef std::function<double(double,double)> Function;
Run Code Online (Sandbox Code Playgroud)
这是我面临的问题:假设函数f
和g
类型都在Function
内部执行昂贵且相同的计算以获得最终结果.为了提高效率,可以将所有公共数据包装在一起struct
,计算一次并作为参数提供给它们.但是,这种设计有几个缺陷.例如,这会导致签名的更改Function
,这可能导致将不必要的参数传递给某些函数实现.而且,这些公共和内部数据不再隐藏在代码中的其他组件中,这可能会损害代码的简单性.
我想讨论以下优化策略:实现一个类CacheFG
:
Update
具有给定一对双精度计算它的内部数据的方法x
和y
; 和Check
方法,以确定是否它的当前内部数据用给定的一对双精度计算x
和y
.那么人们可以做的是创建f
和g
共享类的公共实例CacheFG
,这可以使用std::shared_ptr
构造来完成.所以,下面是创建f
和g
使用辅助功能的功能f_aux
和g_aux …
我pytest
用于测试。我的测试文件驻留在一个子目录tests
,它们被命名Foo.py
,Bar.py
而不是test_Foo.py
,TestFoo.py
等等。所以,要确保pytest
找到他们,我有一个pytest.ini
与下面的内容项目的根目录文件:
[pytest]
python_files=tests/*py
Run Code Online (Sandbox Code Playgroud)
如何pytest.ini
在 Visual Studio Code 中指定文件的路径,以便vscode-python
插件可以正确/成功地发现我的测试文件?无论我尝试什么,我都会得到Test discovery failed
,没有给出任何理由。
c++ ×5
c++11 ×5
f# ×3
shared-ptr ×2
bind ×1
clang ×1
constraints ×1
doxygen ×1
gdb ×1
generics ×1
interface ×1
namespaces ×1
optimization ×1
polymorphism ×1
printing ×1
pytest ×1
stl ×1
syntax ×1
templates ×1