class P
{
};
template< typename P >
class C : public P
{
public:
void f()
{
P::f();
}
};
int main() {
C<P> c1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为了防止我的问题留下任何误解的空间,这是一个代码示例.如果C
是没有模板,但是从继承P
直接,那么样品将无法编译,因为明确的功能f()
试图呼吁基类的功能P
是不存在的.
但是如果C
是模板化的话,那么只有在f()
实际调用时才会被拾取.
我想知道为什么会有这种差异.在这两种情况下f()
都是死代码并且无论如何都会被剥离,但程序在非模板场景中是不正确的.
我有一些代码在VS2015下失败,但在GCC下工作.我很确定这个bug是Visual Studio的,但我想确保我对decltype(auto)的理解是正确的.
#include <iostream>
using namespace std;
string zero_params()
{
return "zero_params called.";
}
template< typename F >
auto test1( F f ) -> decltype(auto)
{
return f();
}
int main() {
cout << std::is_rvalue_reference< decltype(test1(zero_params)) >::value << endl;
cout << test1(zero_params) << endl;
cout << "Done!" << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在Visual Studio下,zero_params返回的字符串被推导为右值引用.此外,该对象的析构函数在test1()中调用,其中从f调用返回f(这似乎是破坏&&对象的合理位置).
在GCC下,返回的字符串不会被推断为右值引用.正如我所期望的那样,在cout语句中使用后调用析构函数.
在Visual Studio下将返回类型指定为'string'而不是decltype(auto)可以修复它,就像在test1中返回f()时使用remove_reference_t一样.
我的期望是GCC是正确的,因为zero_params()的函数签名是字符串,而不是字符串&&所以如果它使用decltype(auto),我会期望非引用'冒泡'到test1的返回类型.
这是正确的评估吗?
晚编辑:
我发现使用VS2015解决这个问题的另一种方法是将给定的函数包装在lambda中:
cout << test1(zero_params) << endl;
Run Code Online (Sandbox Code Playgroud)
至:
cout << test1( [](auto&&... ps) { return zero_params(std::forward<decltype(ps)>(ps)...); } ) << endl;
Run Code Online (Sandbox Code Playgroud) 我有一些代码在GCC下工作,但无法在Visual Studio 2015下编译(我意识到它正在开发中,但我认为应该实现这个领域).
template< typename... T >
class inherit : public T...
{
public:
inherit(T... t) : T(t)... {}
};
int main() {
auto l1 = []() {};
auto l2 = []() {};
inherit<decltype(l1), decltype(l2)> test(l1, l2);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是代码片段简化为它的纯粹本质.Visual Studio在继承的构造函数上说"语法错误:'type'".然后它会稍微探讨它是如何到达那里的,并以"你不能构建一个lambda实例"结束.
我的假设是T(t)的扩展......没有正确扩展.但是我可能会错误地使用语法.
编辑:对不起,问题是:我在这里有错吗?如果是这样,那么正确的语法是什么?
其他发现:为了与我所拥有的回复保持一致,这似乎是Visual Studio 2015在此领域存在错误的问题.在测试中,它似乎是扩展,其中构造函数params被传递给具有问题的lambda基类.以下测试在VS2015下运行:
template< typename T1, typename T2, typename... T3 >
class inherit2 : public T3...
{
public:
inherit2(T1 t1, T2 t2) : T1(t1), T2(t2) {}
};
int main() {
auto l1 = []() …
Run Code Online (Sandbox Code Playgroud) 在过去的几个月里,我一直在花一些空闲时间来阅读有关 Monad 的文章。自从大学时代以来,我就没有使用过函数式语言。所以我不太记得 Haskell,当然也不知道 Scalaz。
学习洋葱、墨西哥卷饼和三明治,同时尝试将这些食物与大量 Haskell 代码关联起来,这是一段艰难的时光。幸运的是,我偶然发现了两篇关键文章,这让我大吃一惊:图片中的单子,以及另一个来自命令式编码背景的人,他简单地写了相当于以下内容的内容:
a -> b becomes m[a] -> m[b] (functor)
a -> m[b] becomes m[a] -> m[b] (monad)
and applicative is just a "function with context"
Run Code Online (Sandbox Code Playgroud)
连同描述bind目的的最简单的句子一起,内函子的许多类别爆炸并变得简单。
Identity、List、Maybe 等突然变得有意义了。在这些知识的推动下,我开始尝试使用一元类型在 C++ 中尝试一些 TMP,看看它会如何实现。
很快我就想传播状态。我想我现在读到的关于状态 monad 和 monad 转换器的文章比我一开始读的关于 monad 的文章还要多,但我一生都无法理解它们。我确信许多键盘已经磨损了,因为这些主题上输入的所有单词都回答了像我这样的人。
但我请你再受一点苦。
a -> s -> (b, s)
Run Code Online (Sandbox Code Playgroud)
函数接受一个值和某个状态,返回一个新值和(可能)修改后的状态。Bind 显然需要将返回值和状态传播到下一个函数中。
我的问题是这样的: monad 的工作是因为它们强加了一个结构。坚持结构并遵守法律会带来乐趣和彩虹。然而 a -> s -> (b, s) 看起来并不像一元 a -> m[b]。
即使应用'a',它仍然是s -> (b, s)。区别在于后一个函数采用(单子?)STATE 并返回带有值的状态。而常规形式是:接受一个 VALUE 并返回一个 WRAPPED 值。
传入的参数以及返回类型的形式都会有所不同。然而许多文章都说这显然看起来像一个单子。对我来说肯定不是。
如果我要放松一下我被告知必须持有的观点:它不是将 m[a] 绑定到 …
我写了一个python模块。它驻留在一个回购。现在要运行模块的单元测试,它们不能是该模块的子文件夹。解决此问题的建议结构是:
ModuleRepo/
MyModule/
__init__.py
some_utils.py
import .some_helpers
some_helpers.py
Tests/
some_utils_test.py
import MyModule.some_utils
some_helpers_test.py
import MyModule.some_helpers
Run Code Online (Sandbox Code Playgroud)
现在效果很好。如果我运行测试,他们就可以导入模块。该模块能够通过前置 '.' 导入自己的文件(例如:some_helpers)。表示本地文件夹。
问题是一个不同的 repo 现在想要共享这个模块,我不知道如何让它找到该模块。
例如:
ModuleRepo/
MyModule/
__init__.py
...
Tests/
...
AnotherRepo/
using_my_module.py
import ??? <-- how to find MyModule?
Run Code Online (Sandbox Code Playgroud)
不工作的尝试 #1: 我最初尝试使用 git 的子模块功能将 ModuleRepo 包含在 AnotherRepo 下。但是我实际上并不想要ModuleRepo的根文件夹,我只想要子文件夹“MyModule”。事实证明 git 的子模块并没有这样做 - 一个人不能只选择要包含的回购的一部分。
不受欢迎的符号链接:虽然符号链接可能有效,但它不能“提交”到存储库,因此有些不受欢迎。此外,我正在 Windows 和 Linux 上进行开发,因此我需要一个适用于两者的解决方案。
可能的解决方案:将 ModuleRepo root 也变成一个模块(添加一个init .py)。然后我可以使用 git 使其成为 AnotherRepo 的子模块。我的导入会很丑,但它会是: import my.module.some_utils 而不是 import mymodule.some_utils
有没有人有更好的解决方案?