小编lo *_*cre的帖子

类型和重载,连接是什么?

我目前正在尝试围绕类型类和实例,我还不太明白它们的意义.到目前为止,我对此事有两个问题:

1)当函数使用该类型类中的某些函数时,为什么必须在函数签名中使用类型类.例:

f :: (Eq a) => a -> a -> Bool
f a b = a == b
Run Code Online (Sandbox Code Playgroud)

为什么要(Eq a)签名.如果==没有定义a那么为什么不在遇到时抛出错误a == b?必须提前声明类型类有什么意义?

2)类型类和函数重载如何相关?

这样做是不可能的:

data A = A
data B = B

f :: A -> A
f a = a

f :: B -> B
f b = b
Run Code Online (Sandbox Code Playgroud)

但是可以这样做:

data A = A
data B = B

class F a where
  f :: a -> a

instance F A …
Run Code Online (Sandbox Code Playgroud)

haskell overloading typeclass

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

未找到标题`execution`和`std :: reduce`

我试图让这个片段编译

#include <vector>
#include <numeric>
#include <execution>

double result = std::reduce(std::execution::par, v.begin(), v.end());
Run Code Online (Sandbox Code Playgroud)

我试过这些编译器:

Apple LLVM version 8.1.0 (clang-802.0.42)

clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)

g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
Run Code Online (Sandbox Code Playgroud)

这三个人都给了我 'execution' file not found

分别 error: no member named 'reduce' in namespace 'std' auto result = std::reduce(v.begin(), v.end());

对于这个片段

#include<numeric>
#include<vector>

int main(int argc, char *argv[])
{
    std::vector<double> v(10, 1);

    auto result = std::reduce(v.begin(), v.end());
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我想我的编译器太旧了?但是在cppreference上它没有说明哪个编译器版本最低,而且我没有在repo中看到任何更新版本的clang或gcc.

c++ header c++17

11
推荐指数
2
解决办法
4419
查看次数

在可变参数模板参数中混合类型和非类型?

是否可以在可变参数模板参数中混合类型和非类型?如果我将一个std::arrayfor例作为参数传递给这个类T,我还需要传递一个数组类型和一个长度,但是我在下面尝试它的方式在遇到一个值时会导致错误,因为它只需要类型为Types:

template <
    template<class, std::size_t>  class T,
    class ... Types>
class C {

    T<Types...> storage;
};

int main(){
    C<std::array, int, 3> c;
}
Run Code Online (Sandbox Code Playgroud)

错误信息:

error: template argument for template type parameter must be a
      type
    Container<std::array, int, 3> c;
                               ^
Run Code Online (Sandbox Code Playgroud)

有没有办法在可变参数上下文中传递类型和值?

c++ variadic-templates

9
推荐指数
2
解决办法
1062
查看次数

如何从参数包中定义值类型的元组

我需要构建一个n类型的元组.这n种类型是n种其他类型的值类型.请考虑以下代码段:

#include <boost/hana.hpp>

namespace hana = boost::hana;

template<class... Types>
class CartesianProduct
{
public:
    CartesianProduct(Types... args) : sets(args...) {}

    hana::tuple<Types...> sets;
    hana::tuple<Types...::value_type> combination; // does not work obviously... but wo can this be done?
};
Run Code Online (Sandbox Code Playgroud)

应用程序的目的是这样的:我向这个类传递一个可能不同类型的容器的参数包.该类将这些容器放入元组中sets.该类还有一个字段combination,它是容器传递给类的元素数量的元组.但元素的类型是不同容器的值类型.

然后,该类旨在懒惰地构建传递给它的容器的笛卡尔积,并将当前组合存储在其中combination.但是,我怎样才能以可变方式实际获取容器的值类型?

c++ tuples variadic-templates boost-hana

9
推荐指数
2
解决办法
1419
查看次数

取消引用字符串迭代器会产生int

我收到这个错误

comparison between pointer and integer ('int' and 'const char *')
Run Code Online (Sandbox Code Playgroud)

对于以下代码

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

int main()
{
    std::string s("test string");
    for(auto i = s.begin(); i != s.end(); ++i)
    {
        cout << ((*i) != "s") << endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么解引用字符串迭代器会产生一个int而不是std::string

c++ string iterator dereference

6
推荐指数
1
解决办法
1386
查看次数

为什么CRTP不会导致无限嵌套?

我对CRTP的编译方式感到困惑.如果我们有这样的事情:

template<class T>
class Base
{

};
class Derived : public Base<Derived>
{

};
Run Code Online (Sandbox Code Playgroud)

为什么在编译期间没有类似的事情发生?

(X[Y]表示X继承自Y)

在声明Derived实例时 Derived d;

d 正在扩展为模板和继承的无限复发

d[Base<Derived[Base<Derived[Base<Derived[Base<Derived[...]>]>]>]>]

为什么这不会发生?关于CRTP的所有教程只解释了你可以用它做什么,而不是在幕后发生的事情(至少含糊不清).

c++ inheritance crtp template-meta-programming

6
推荐指数
1
解决办法
131
查看次数

为什么在C++ 11中允许第二次初始化

在C++ 11下,可以在声明时直接初始化类成员.但是也可以在构造函数的初始化列表中再次初始化它们......为什么?

#include <iostream>



struct MyStr
{

    MyStr()
    :j(0)
    {
        std::cout << "j is " << j << std::endl; // prints "j is 0"
    }

    const int j = 1;

};

int main()
{
    const int i = 0;

    MyStr mstr; 
}
Run Code Online (Sandbox Code Playgroud)

因为做这样的事情是一个错误,可以理解:

MyStr()
:j(0),
j(1)
{
}
Run Code Online (Sandbox Code Playgroud)

第一个例子有什么不同,数据成员在声明时初始化,然后再在构造函数的初始化列表中初始化?

c++ initialization c++11

5
推荐指数
2
解决办法
293
查看次数

使用模板基类的模板函数声明

我想使用基类的模板函数,如下所示:

struct A {
  template <class T> static auto f() { \*code*\ }
};

template <class A_type> struct B : public A_type {

  using A_type::f;

  void g() { auto n = f<int>(); }
};
Run Code Online (Sandbox Code Playgroud)

但是,这不会编译。

error: expected '(' for function-style cast or type
      construction
  void g() { auto n = f<int>(); }
                        ~~~^
error: expected expression
  void g() { auto n = f<int>(); }
Run Code Online (Sandbox Code Playgroud)

但是直接引用基类而不是模板确实有效:

struct A {
  template <class T> static auto f() { \*code*\ }
};

template <class …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance templates using-statement

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

Valgrind导致双打长数值问题

我的代码中具有以下功能,用于检查数字(在日志空间中)是否具有允许的值:

template<class T>
static void check_if_normal(T t)
{
    T additive_neutral_element = make_additive_neutral_element<T>();
    // probability is allowed to be 0 in logspace
    // probability also is allowed to be -inf in logspace
    if (!std::isnormal(t) && t != 0 && t != additive_neutral_element)
        throw std::underflow_error(
          "Probability of " + std::to_string(t) +
          " is abnormal --- possible cause underflow.");
}
Run Code Online (Sandbox Code Playgroud)

在使用此函数的上下文中,我排他性地使用了长双精度。当我在不使用valgrind的情况下运行程序时,一切正常,但是当我在使用valgrind的程序运行时,该函数实际上会引发异常。我怀疑valgrind所做的事情会改变长双打的格式,或者类似的行为。我找到了这个:

Valgrind在相对于IEEE754的x86 / AMD64浮点实现中具有以下限制。

精度:不支持80位算术。在内部,Valgrind用64位表示所有此类“长双精度”数字,因此结果可能有所不同。这是否很关键还有待观察。请注意,x86 / amd64 fldt / fstpt指令(读/写80位数字)已使用到64位的转换进行了正确模拟,因此,如果有人要查看,则80位数字的内存图像看起来正确。

从许多FP回归测试中观察到的印象是,准确性差异并不明显。一般而言,如果程序依赖于80位精度,则可能很难将其移植到仅支持64位FP精度的非x86 / amd64平台。即使在x86 / amd64上,该程序也可能会获得不同的结果,具体取决于它是编译为使用SSE2指令(仅64位)还是x87指令(80位)。最终结果是使FP程序的行为就像在具有64位IEEE浮点数的计算机(例如PowerPC)上运行时一样。在amd64上,FPD算术运算默认情况下是在SSE2上完成的,因此从FP角度来看,amd64看起来更像PowerPC,而不是x86,并且与x86相比,明显的精度差异要少得多。

舍入:Valgrind确实对以下转换遵循4种IEEE规定的舍入模式(至最接近,至+无限,至-无限,至零):浮于整数,整数可能浮于精度的情况,以及浮动到浮动的舍入。对于所有其他FP操作,仅支持IEEE默认模式(四舍五入到最接近)。

FP代码中的数字异常:IEEE754定义了五种可能发生的数字异常:无效操作(负数的平方等),被零除,溢出,下溢,不精确(精度损失)。

对于每个异常,IEEE754定义了两个动作过程:(1)可以调用用户定义的异常处理程序,或者(2)定义一个默认动作,该动作可以“修正”并允许计算继续进行而无需引发异常。

当前,Valgrind仅支持默认的修正操作。同样,对于异常支持的重要性的反馈将不胜感激。

当Valgrind检测到程序试图超出这些限制中的任何一个(设置异常处理程序,舍入模式或精度控制)时,它可以打印一条消息,提供对该事件发生的位置的追溯,并继续执行。此行为曾经是默认行为,但是消息很烦人,因此默认情况下现在禁用显示消息。使用--show-emwarns = yes可以查看它们。

以上限制精确地定义了IEEE754的“默认”行为:所有异常的默认修正,最近舍入操作和64位精度。 …

c++ valgrind numeric long-double

5
推荐指数
0
解决办法
332
查看次数

从跟踪隐藏谓词

有没有办法从跟踪中隐藏单个谓词?在这样的规则中:

p(<Stuff>) :-
    q(),
    p(<ModifiedStuff>);
    s(),
    p(<ModifiedStuff>);
    p(<ModifiedStuff>).
Run Code Online (Sandbox Code Playgroud)

例如,我想隐藏q()和隐藏s()踪迹,因为我仅对的调用感兴趣p()q()并且s()可能会调用许多其他谓词,这完全阻塞了跟踪,并使其很难在其中找到相关的调用。

编辑1

现在,我尝试从命令行而不是从解释器内部执行,并将跟踪管道传递给grep以对包含p...的行进行grepping ,但令我失望的是,从命令行运行时,它仍然打开了一个prolog shell,因此,对输出进行管道传输根本不起作用。只有print将实际发送到运行Prolog进程的Shell。

编辑2(使用trace(p,all)时输出)

?- trace(shift_reduce, all).
%         shift_reduce/2: [call,redo,exit,fail]
true.

[debug]  ?- shift_reduce([?,x,x], T).
 T Call: (8) shift_reduce([?, x, x], _7344)
 T Exit: (8) shift_reduce([?, x, x], [e, [?], [v, [x]], [e, [v, [...]]]])
T = [e, [?], [v, [x]], [e, [v, [x]]]] ;
 T Exit: (8) shift_reduce([?, x, x], [e, [?], [v, [x]], [e, …
Run Code Online (Sandbox Code Playgroud)

trace prolog swi-prolog

5
推荐指数
0
解决办法
264
查看次数