小编Job*_*Job的帖子

STL中有"魔力"吗?

让我先解释一下我对"魔法"的意思.我将使用Java中的两个示例:

  1. 每个类都继承(直接或间接)Object类.
  2. Java不支持运算符重载,但+String对象定义了运算符.

这意味着不可能在纯(*)Java中实现ObjectString类的实现.现在这就是我对"魔术"的意思:要实现这些类,您需要编译器的一些特殊支持.

我一直喜欢C++的是,据我所知,STL中没有这样的"神奇",即可以在纯C++中实现STL.

现在我的问题是:这是真的吗?或者是否有STL的部分无法在纯C++中实现并需要一些"魔术"/特殊编译器支持?


(*)"纯"是指不使用任何类库.

c++ stl std

47
推荐指数
7
解决办法
2853
查看次数

如何在OpenCv中将cv :: Mat转换为灰度?

如何将cv :: Mat转换为灰度?

我试图从opencv运行drawKeyPoints func,但是我收到了Assertion Filed错误.我的猜测是它需要在参数中接收灰度图像而不是彩色图像.

void SurfDetector(cv::Mat img){
vector<cv::KeyPoint> keypoints;
cv::Mat featureImage;

cv::drawKeypoints(img, keypoints, featureImage, cv::Scalar(255,255,255) ,cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);

cv::namedWindow("Picture");
cv::imshow("Picture", featureImage);
Run Code Online (Sandbox Code Playgroud)

}

c++ variables opencv grayscale

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

C头问题:#include和"未定义引用"

好吧,我一直试图用这个工作的时间最长,而我似乎无法让它正常工作.我有三个文件,main.c,hello_world.c,和hello_world.h.无论出于何种原因,他们似乎没有很好地编译,我真的无法弄清楚为什么......

这是我的源文件.首先是hello_world.c:

#include <stdio.h>
#include "hello_world.h"

int hello_world(void) {
  printf("Hello, Stack Overflow!\n");
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后hello_world.h,简单:

int hello_world(void);
Run Code Online (Sandbox Code Playgroud)

最后是main.c:

#include "hello_world.h"

int main() {
  hello_world();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我把它放入GCC时,这就是我得到的:

cc     main.c   -o main
/tmp/ccSRLvFl.o: In function `main':
main.c:(.text+0x5): undefined reference to `hello_world'
collect2: ld returned 1 exit status
make: *** [main] Error 1

有人能帮帮我吗?我真的坚持这个,但我99%肯定这是一个非常简单的修复.

c gcc header header-files undefined-reference

23
推荐指数
3
解决办法
6万
查看次数

如何使用make和编译为C99?

我正在尝试使用Makefile编译linux内核模块:

obj-m += main.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Run Code Online (Sandbox Code Playgroud)

这给了我:

main.c:54: warning: ISO C90 forbids mixed declarations and code
Run Code Online (Sandbox Code Playgroud)

我需要切换到C99.阅读后我注意到我需要添加一个标志-std = c99,不确定它在哪里添加.

如何更改Makefile以便它编译为C99?

linux makefile c99 c89 kbuild

19
推荐指数
3
解决办法
3万
查看次数

使用接口包装库而无需向下转发

假设我的项目使用了一个库,LibFoo它通过许多类来提供它的功能,比如说FooAFooB.现在,有许多类似的库(例如,LibBar提供BarA和提供BarB)提供相同的功能LibFoo,我希望我的项目用户能够选择使用哪个库,最好是在运行时.

为了实现这一点,我创建了一个"包装层",它定义了我期望从库中获得的接口.在我的示例中,该层包含两个接口:IfaceAIfaceB.然后,对于我想要支持的每个库,我创建了一个"实现层",使用其中一个库实现接口.

我现在的问题在于如何很好地实现实现层.为了演示我的问题,请考虑我们有以下接口(以C++显示,但应适用于类似语言):

class IfaceA
{
public:
    virtual void doSomethingWith(IfaceB& b) = 0;
    ...
};

class IfaceB
{
    ...
};
Run Code Online (Sandbox Code Playgroud)

实现层中的类LibFoo将保存来自相应类的对象LibFoo.应使用这些对象实现接口中的操作.因此(请原谅我可怕的名字):

class ConcreteAForFoo : public IfaceA
{
public:
    void doSomethingWith(IfaceB& b) override
    {
        // This should be implemented using FooA::doSomethingWith(FooB&)
    }

private:
    FooA a;
};

class ConcreteBForFoo : public IfaceB
{
public:
    FooB& getFooB() const
    {
        return b; …
Run Code Online (Sandbox Code Playgroud)

c++ oop interface

19
推荐指数
4
解决办法
993
查看次数

为什么amd64 linux中的系统调用号码不同?

我注意到x86 int $0x80和amd64 syscall系统调用有不同的数字.例如,sys_exitx86中的syscall 1和amd64中的syscall 60.是否存在不同系统呼叫编号方案的(历史)原因?

linux x86-64 naming-conventions system-calls

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

金丝雀是否会阻止返回libc和面向返回的编程攻击?

我试图了解如果使用金丝雀,是否/如何返回到libc和面向返回的编程漏洞是可能的.
金丝雀将被放置在返回值和要溢出的缓冲区之间的堆栈上,并且需要被覆盖以便将返回值更改为库函数或计算的位置.金丝雀自1997年以来一直存在(StackGuard),而ROP是2007年首次推出的技术(Shacham).

金丝雀是否无法进行这些类型的攻击?

stack-overflow security exploit

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

为包含指针的结构创建MPI_Datatype

我有以下结构.

typedef struct
{
 int *Ai;
 double *Ax;
 int nz;
}column;
Run Code Online (Sandbox Code Playgroud)

我想用MPI_Send和转移这个结构MPI_Receive.如何MPI_Datatype为此结构创建?

c mpi

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

使用GCC的内联汇编直接调用

如果要从内联汇编中调用C/C++函数,可以执行以下操作:

void callee() {}
void caller()
{
    asm("call *%0" : : "r"(callee));
}
Run Code Online (Sandbox Code Playgroud)

然后GCC将发出如下所示的代码:

movl $callee, %eax
call *%eax
Run Code Online (Sandbox Code Playgroud)

这可能会有问题,因为间接调用会破坏旧CPU上的管道.

由于地址callee最终是常量,可以想象可以使用i约束.引自GCC在线文档:

'我"

允许使用立即整数操作数(具有常量值的操作数).这包括符号常量,其值仅在汇编时或以后知道.

如果我尝试这样使用它:

asm("call %0" : : "i"(callee));
Run Code Online (Sandbox Code Playgroud)

我从汇编程序中收到以下错误:

错误:后缀或操作数对`call'无效

这是因为GCC会发出代码

call $callee
Run Code Online (Sandbox Code Playgroud)

代替

call callee
Run Code Online (Sandbox Code Playgroud)

所以我的问题是是否可以使GCC输出正确call.

c c++ gcc inline-assembly function-call

11
推荐指数
1
解决办法
9852
查看次数

用于循环索引类型演绎的最佳实践

比方说,我有一个c提供size()方法的类型的容器,我想循环遍历这个容器,同时跟踪每个项目的索引:

for (/*TODO*/ i = 0; i < c.size(); i++) {...}
Run Code Online (Sandbox Code Playgroud)

在后C++ 11世界中,自动类型演绎很好地解决了很多问题.我们应该用什么来取代TODO上述?对我来说唯一正确的,无论类型size()是什么,如下:

for (decltype(c.size()) i = 0; i < c.size(); i++) {...}
Run Code Online (Sandbox Code Playgroud)

但这看起来过于冗长,在我看来,这无助于可读性.

另一种解决方案可能是:

for (auto end = c.size(), i = 0; i < end; i++) {...}
Run Code Online (Sandbox Code Playgroud)

但这也无助于可读性,当然,它与原始片段没有相同的语义.

所以,我的问题是:只给出索引限制的类型,推断循环索引变量类型的最佳方法是什么.

c++ c++11 type-deduction

11
推荐指数
1
解决办法
959
查看次数