小编qea*_*adz的帖子

为什么模板类允许无法编译的成员函数?

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()都是死代码并且无论如何都会被剥离,但程序在非模板场景中是不正确的.

c++ templates

16
推荐指数
3
解决办法
990
查看次数

在临时之前调用的析构函数应该超出范围

我有一些代码在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)

c++ decltype auto c++14 visual-studio-2015

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

它是编译器还是仅仅是我:继承自lambda所包含的可变参数模板

我有一些代码在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)

lambda templates variadic c++11 visual-studio-2015

10
推荐指数
1
解决办法
236
查看次数

状态单子如何工作?(无代码说明)

在过去的几个月里,我一直在花一些空闲时间来阅读有关 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] 绑定到 …

monads state-monad

5
推荐指数
1
解决办法
829
查看次数

从另一个 repo 导入 python 模块

我写了一个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

有没有人有更好的解决方案?

python git project repository git-submodules

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