小编n. *_* m.的帖子

GHCi下的动态加载

我需要能够动态加载Haskell模块,并在动态加载模块的上下文中计算表达式.

提示做到了; 问题是,它至少在Windows上不适用于GHCi.

cygwin-bash> ghci HintTest.hs
GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Ok, modules loaded: Main.
Prelude Main>
Prelude Main> main
[... lots of "Loading package" messages snipped]

GHCi runtime linker: fatal error: I found a duplicate definition for symbol
   _debugLn
whilst processing object file
   C:\PROGRAM FILES (X86)\HASKELL PLATFORM\2013.2.0.0\lib\ghc-prim-0.3.0.0\HSghc-prim-0.3.0.0.o
This could be caused by:
   * Loading two …
Run Code Online (Sandbox Code Playgroud)

haskell dynamic-loading ghci

17
推荐指数
1
解决办法
631
查看次数

通过extern"C"函数与C++对象的接口

一个可以extern "C"函数接受或返回C++ -特定的数据类型,如参考文献,指针到成员或非POD类(由值)?我在C++标准中找不到禁止此内容的任何内容.从逻辑上讲,我希望标准可以说一些,因为C ABI不一定适合传递这类类型.

我想要使​​用C链接的原因与C编译器无关.该函数仅从C++代码调用.我只想从动态库中导出未编码的函数名.

一个愚蠢的代码示例:

class Foo {
  public:
    virtual void doit() = 0;
};

class Bar : public Foo {
  public:
    void doit() { std::cout << "Bar" << std::endl; }
};

extern "C" Foo& getFoo() { static Bar bar; return bar; }

extern "C" Bar getBar() { return Bar(); }
Run Code Online (Sandbox Code Playgroud)

这在Linux上用GCC编译,并按预期工作.应该是标准吗?

问题是对这个问题的评论中的讨论的后续行动.

更新我用Comeau编译器对此进行了测试,它没有抱怨.

c++ standards linkage

16
推荐指数
1
解决办法
2868
查看次数

对于嵌套在类模板中的类X,operator <<(ostream&,X)

这个编译和工作应该(非嵌套模板):

#include <iostream>

template<typename T> class Z;

template <typename T> 
std::ostream& operator<< (std::ostream& os, const Z<T>&) {
    return (os << "Z");
}

template<typename T> class Z {
    friend std::ostream& operator<< <> (std::ostream& os, const Z&);
};

int main () {
    Z<int> z;
    std::cout << z << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

这个不编译(gcc 4.4和gcc 4.6,在03和0x模式下):

#include <iostream>

template<typename T> class Z;

template<typename T> 
std::ostream& operator<< (std::ostream& os, const typename Z<T>::ZZ&) {
    return (os << "ZZ!");
}

template <typename T> class Z {
  public:
    class …
Run Code Online (Sandbox Code Playgroud)

c++ templates

15
推荐指数
2
解决办法
1904
查看次数

具有依赖类型的字符串文字 - 不可能?

是否可以定义用户定义的字符串文字转换运算符,使其结果的类型取决于其字符串输入的值?

用户定义的整数和浮点文字很容易,因为它们允许文字运算符模板,文字的实际字符作为模板参数传递给它.例:

template <char... s> struct silly { using type = int; };
template <char... s> struct silly<'1', s...> { using type = double; };

template <char... s>
typename silly<s...>::type operator"" _silly() { return 0; }

static_assert(std::is_same<int, decltype(4321_silly)>::value, "no luck");
static_assert(std::is_same<double, decltype(1234_silly)>::value, "no luck");
Run Code Online (Sandbox Code Playgroud)

用户定义的字符串文字似乎不存在这样的事情.

是否有另一种方法可以做到这一点,无论是在现行标准中,还是计划/讨论过的未来版本?

c++ user-defined-literals c++11

15
推荐指数
1
解决办法
374
查看次数

传递大括号列表参数时调用可变参数函数模板的问题

考虑这个功能模板:

template <class... T>
void foo (std::tuple<T, char, double> ... x);
Run Code Online (Sandbox Code Playgroud)

此调用有效:

using K = std::tuple<int, char, double>;
foo ( K{1,'2',3.0}, K{4,'5',6.0}, K{7,'8',9.0} );
Run Code Online (Sandbox Code Playgroud)

这个没有:

foo ( {1,'2',3.0}, {4,'5',6.0}, {7,'8',9.0} );
Run Code Online (Sandbox Code Playgroud)

(gcc和clang都抱怨过多论据foo)

为什么第二次调用有问题?我可以重写声明,foo以便第二次通话也被接受吗?

模板参数T仅用于实现可变参数.实际类型是已知和固定的,只有参数的数量不同.在现实生活中,类型不同int, char, double,这只是一个例子.

我不能使用C++ 17.更喜欢C++ 11兼容的解决方案.

c++ variadic-templates c++11 list-initialization

15
推荐指数
1
解决办法
544
查看次数

std::array 的分段初始化

如何编写std::array串联函数?

template <typename T, std::size_t sza, std::size_t szb>
std::array<T, sza+szb> concat (const std::array<T, sza>& aa, 
                                const std::array<T, szb>& ab)
{
    std::array<T, sza+szb> result;
    std::copy(std::begin(aa), std::end(aa), std::begin(result));
    std::copy(std::begin(ab), std::end(ab), std::begin(result) + sza);
    return result;
}
Run Code Online (Sandbox Code Playgroud)

T当不可默认构造时,这当然不起作用。如何解决这个问题?

c++ stdarray c++20

15
推荐指数
3
解决办法
780
查看次数

类型系列的难以理解的错误消息

我试图理解类型家庭没有太大的成功.这是一个最小的例子:

{-# LANGUAGE TypeFamilies #-}

class Object obj where
  type Unit obj :: *
  unit :: Unit obj

instance (Object obj, Object obj') => Object (obj, obj') where
  type Unit (obj, obj') = (Unit obj, Unit obj')
  unit = (unit, unit)
Run Code Online (Sandbox Code Playgroud)

我认为目的是相当透明的(尝试定义产品类别).

这给了我:

objs.hs:10:10:
    Could not deduce (Unit obj' ~ Unit obj1)
    from the context (Object obj, Object obj')
      bound by the instance declaration at objs.hs:8:10-56
    NB: `Unit' is a type function, and may not be injective
    The type variable …
Run Code Online (Sandbox Code Playgroud)

haskell type-families

14
推荐指数
1
解决办法
467
查看次数

如何摆脱$(...)和[| 使用Template Haskell函数时的... |]语法?

我正在尝试学习一些模板Haskell.作为练习,我写的,可以生成诸如函数isLeftisRight(灵感来自这个问题).这是我谦虚的尝试:

isA connam = do
    ConE nam <- connam
    nn <- newName "p"
    lamE [varP nn] $ caseE (varE nn) [
                       match (conP nam [wildP]) ( normalB [| True |] ) [],
                       match wildP ( normalB [| False |] ) [] 
                     ]
Run Code Online (Sandbox Code Playgroud)

问题是我必须写$(isA [| Left |])而不是更直观isA Left.是否有可能摆脱丑陋的语法?我似乎无法在文档中找到答案.

该函数仅适用于单参数构造函数,但这是另一个问题.

haskell template-haskell

12
推荐指数
1
解决办法
469
查看次数

g ++未报告未实例化模板中的某些错误

考虑这个例子:

class A
{
  void foo();
  public:
  void bar();
};

template <class> class B
{
  B()
  {
    A a;
    a.foo();    // 1
    A::bar();   // 2
    a.bar(1);   // 3
  }
};
Run Code Online (Sandbox Code Playgroud)

注意B永远不会被实例化.

clang++报告所有三条标记的行都是错误的.g++(4.8.3)接受行1,2并且仅报告行3.

如果B实例化,请g++愉快地将所有三行报告为错误.

这是一个g++错误吗?有人会这么认为.A不是依赖名称,应在模板定义时正常检查其成员.我看不到细微差别吗?

c++ templates g++

12
推荐指数
2
解决办法
413
查看次数

如何强制g ++内联函数?

在使用Haskell FFI到C/C++时,我最近遇到了C++内联函数的问题.也就是说,g ++并不真正内联声明的函数inline,并为它们生成符号.最终,当ghci尝试加载调用内联函数的目标文件时,这会生成链接器错误:

Loading object (static) solveeq.o ... done
Loading object (dynamic) /usr/lib/gcc/x86_64-linux-gnu/4.6/libstdc++.so ... done
final link ... ghc: solveeq.o: unknown symbol `_ZN5Eigen8internal19throw_std_bad_allocEv'
Run Code Online (Sandbox Code Playgroud)

这里,_ZN5Eigen8internal19throw_std_bad_allocEvinline仅在标题的Eigen C++库中的函数,以某种方式被视为实函数并给出了链接器符号.solveeq.o是我的目标文件,它对该函数进行(间接)调用.环境是Ubuntu 12.04 64bit,ghc 7.4.1.

问题是这样的:我可以extern "C" 用来阻止C++为我自己的函数装饰函数名.但我不能/不应该更改其他人定义的C++标头(原因很明显).在我看来,编译器不应该首先为此内联定义创建一个函数来导致此错误.原因很简单.如果有问题的函数是真正内联的,我不会得到链接器错误.如果编译器变得聪明并决定为它创建一个真正的函数,我会得到这样的错误(或者我在其他地方读到的同一函数的多个定义).所以现在,编译/链接的正确性取决于编译器的情绪.

此外,我认为像这样的链接器问题实际上会破坏仅限标头的C++库(它们具有吸引力),因为现在无法使用它们进行导出extern "C".

这是c ++的设计问题还是仅仅是一个g ++问题?我的问题是,有没有办法阻止c ++编译器或g ++不内联内联函数?例如,是否有一个命令行选项?(修改源代码是不可能的,因为它们是库代码.)

另外,我很好奇C++ STL是如何处理这个问题的.它们也只是标题吗?

c++ haskell inline ffi ghci

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