小编sap*_*sap的帖子

通过值(?)而不是函数指针传递函数?

对不起,如果之前已经询问过,但我找不到它.

因此,我试图教自己关于模板和新的C++ 11功能(主要是lambdas,我一直喜欢的其他语言).

但是在我的测试中,我找到了一些我不知道它有效的东西,我试图理解它是如何工作的,但是无法弄清楚它.

以下代码:

template <class Func>
void Test( Func callback ) {
    callback( 3 );
}

void Callback( int i ) {
    std::cout << i << std::endl;
}

int main( int argc, char** argv ) {
    Test( &Callback ); // this I was expecting to work, compiler will see its a pointer to a function
    Test( Callback ); // this also works, but how?!
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果我理解模板是如何工作的,基本上它们是编译器知道要构建什么的方案,所以第一次调用Test( &Callback );我期望工作,因为编译器将看到模板接收函数地址并假设参数应该是指针.

但是第二个电话是什么?假设是什么模板?一个函数的副本(如果它甚至有意义)?

c++ templates function c++11

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

没有成本的工作分配,匈牙利方法会起作用吗?

所以我有一个工作分配问题,没有匈牙利方法所需的传统成本.

例如:

I have 3 workers - A, B and C
I have 5 jobs -  1, 2, 3, 4 and 5
Run Code Online (Sandbox Code Playgroud)

每个工人都有他可以执行的工作列表,如下所示:

worker A can work on job 1, 2, 5
worker B can work on job 1, 2
worker C can work on job 1
Run Code Online (Sandbox Code Playgroud)

最终结果(因为没有成本)是我可以实现的最大分配数.在这个例子中,我最多可以完成3个任务:

worker A on job 5
worker B on job 2
worker C on job 1
Run Code Online (Sandbox Code Playgroud)

匈牙利方法是解决这个问题的好方法吗?我应该只使用"虚拟"费用吗?我想也许可以使用工作偏好的指数作为成本; 这是一个好主意吗?

algorithm hungarian-algorithm

7
推荐指数
2
解决办法
1224
查看次数

在开发类似语言的小python时进行缩进控制

我正在使用flex,byacc(用于词法和解析)和C++开发一个类似语言的小python,但我有一些关于范围控制的问题.

就像python一样,它使用白色空格(或制表符)进行缩进,不仅如此,但我想实现索引破坏,例如,如果你在while循环中键入"break 2",那么在另一个while循环中它不仅会从最后一个,但也来自第一个循环(因此在休息后的数字2),依此类推.

例:

while 1
    while 1
        break 2
        'hello world'!! #will never reach this. "!!" outputs with a newline
    end
    'hello world again'!! #also will never reach this. again "!!" used for cout
end
#after break 2 it would jump right here
Run Code Online (Sandbox Code Playgroud)

但由于我没有"反"制表符来检查作用域何时结束(例如C,例如我只使用'}'字符)我想知道这种方法是否最好:

我将在我的yacc文件中定义一个全局变量,如"int tabIndex",我将使用extern在我的lex文件中访问.然后每当我在我的lex文件中找到一个制表符时,我会将该变量增加1.当我在yacc文件上解析时,如果我找到一个"break"关键字,我会减去它从tabIndex变量后面输入的数量,以及我编译后达到EOF并且我得到一个tabIndex!= 0我会输出编译错误.

现在的问题是,最好的方法是查看缩进是否减少,我应该从lex读取\ b(退格)字符然后减少tabIndex变量(当用户不使用break时)?

另一种实现这个的方法?

另外一个小问题,我希望每个可执行文件都有一个名为start()的函数的起点,我应该将其硬编码到我的yacc文件中吗?

对不起,长期以来,我们非常感谢任何帮助.如果有人可以为python提供yacc文件,那么作为指南很好(尝试在谷歌上看,没有运气).

提前致谢.

c c++ yacc lex compiler-theory

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

实现switch类型trait(使用std :: conditional_t链调用)

这就是我想要的,一个"switch"类型特征,它返回第一个有条件== true的类型:

ext::select_t<condition1 == true, Type1,
              condition2 == true, type2,
              condition3 == true, type3>
Run Code Online (Sandbox Code Playgroud)

等,并能够添加尽可能多的条件/类型对.

我可以用std :: conditional这样做(随机例子):

template<typename Number,
         typename Distribution = std::conditional_t<
                 // IF
                 std::is_integral<Number>::value,
                 // RETURN INT
                 std::uniform_int_distribution<Number>,
                 // ELSE
                 std::conditional_t<std::is_floating_point<Number>::value,
                                    // RETURN REAL
                                   std::uniform_real_distribution<Number>, void>>>

Number random(Number min, Number max)
{
    static std::random_device rd;
    static std::mt19937 mt(rd());

    Distribution dist(min, max);

    return dist(mt);
}
Run Code Online (Sandbox Code Playgroud)

你可以看到它在编译时决定我想要什么样的分布,具体取决于传递的条件/类型.

显然,如果我尝试添加更多条件,这可以变得非常难看,想象我想要10个.

所以我试图建立一个,但悲惨地失败了:

template<bool B, typename T>
struct cond
{
    static constexpr bool value = B;
    using type = T;
};

template<typename Head, …
Run Code Online (Sandbox Code Playgroud)

c++ templates type-traits

4
推荐指数
1
解决办法
1014
查看次数

将Qt对象与std :: shared_ptr一起使用

我正在尝试将一个小的实用程序应用程序更新为更现代的C++方式,但是我在使用std :: shared_ptr的一些Qt对象时遇到了问题,特别是那些接收其他QWidget作为构造函数参数的那些.

例如:

private:
    std::shared_ptr<QWidget> centralwidget;
    std::shared_ptr<QVBoxLayout> verticalLayout;

public:
    void setupUi(QMainWindow *MainWindow) // this pointer is a .get() from a shared_ptr
    {
        centralwidget = std::make_shared<QWidget>(new QWidget(MainWindow)); // compiles fine
        verticalLayout = std::make_shared<QVBoxLayout>(new QVBoxLayout(centralwidget.get())); // does not compile
    }
Run Code Online (Sandbox Code Playgroud)

编译错误是:

错误1错误C2664:'QVBoxLayout :: QVBoxLayout(QWidget*)':无法将参数1从'QVBoxLayout*'转换为'QWidget*'e:\ microsoft visual studio 11.0\vc\include\memory 855

我似乎无法理解这个错误,我没有转换任何东西,我只是想创建一个QVBoxLayout对象并传递一个QWidget作为其父(就像我会用原始指针).

c++ qt shared-ptr

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

QThread finished()信号永远不会发出

所以我有一个有2个插槽的工作类:StartWork()和StopWork(),StartWork()运行一个无限循环(它只是读取和读取摄像头输入不停),StopWork()方法只是设置一个bool变量为false(因此StartWork()内的循环停止).

根据QThread文档,现在使用它们的最佳方法不是通过子类化,而是通过将工作者移动到线程中,这就是我所做的.问题是,来自线程的started()信号被调用,但是完成的()信号永远不会被调用.

工人类槽:

void StartWork(){running = true; 而(跑步){做工; }}

void StopWork(){running = false; }

QThread初始化和信号/插槽连接:

thread = new QThread();
worker = new Worker();
worker.moveToThread(thread);

QObject::connect(thread, SIGNAL(started()), worker, SLOT(StartWork()));
QObject::connect(thread, SIGNAL(finished()), worker, SLOT(StopWork()));
Run Code Online (Sandbox Code Playgroud)

在我的QPushButton上,我这样做:

if(pushStartStop->text().toLower() == "start")
{
    pushStartStop->setText("Stop");
    thread->start();
}
else
{
    pushStartStop->setText("Start");
    thread->quit();
}
Run Code Online (Sandbox Code Playgroud)

thread-> start()工作正常,StartWork()被调用,一切都很漂亮(GUI运行没有块等).

但是thread-> quit()没有做任何事情,它被调用(因为按钮改变文本),但就是这样.如果我只是调用worker-> StopWork()它可以工作,但我不能再启动它.

我尝试过thread-> exit(); 但结果是一样的.我也知道子类分类工作,但它看起来更丑陋,根据最近的Qt文档,子分类不再是最佳的.

提前致谢.

c++ qt qthread

2
推荐指数
1
解决办法
2085
查看次数

将容器value_type作为模板参数传递?

是否可以将容器的value_type作为模板参数传递?

就像是:

template<typename VertexType>
class Mesh
{
    std::vector<VertexType> vertices;
};

std::vector<VertexPositionColorNormal> vertices;

// this does not work, but can it work somehow?
Mesh<typename vertices::value_type> mesh;

// this works, but defeats the purpose of not needing to know the type when writing the code
Mesh<typename std::vector<VertexPositionColorNormal>::value_type> mesh;
Run Code Online (Sandbox Code Playgroud)

我在创建网格(第一个)时得到"无效的模板参数",但是它应该正常工作吗?我在编译时传递一个已知类型,为什么它不起作用?有什么替代品吗?

谢谢.

c++ templates stl

2
推荐指数
1
解决办法
665
查看次数

使用工厂朋友班分配新班级,好习惯?

我有一个复杂的类,我想强制用户使用std :: unique_ptr,我认为最好的方法是创建一个返回std :: unique_ptr并隐藏ctor的工厂方法.

问题是,我添加的工厂方法越多,标题和代码开始看起来越脏.

所以我想也许如果我创建一个新的ClassFactory类,其中包含所有工厂方法,它看起来更干净,每次我想添加一个新的工厂方法我只是编辑工厂类并完成它(保留原始班级干净).

例如:

class Widget
{
private:
    friend class WidgetFactory;

    Widget(){}
    Widget(const Widget& other) = delete;
    Widget& operator = (const Widget& other) = delete;

    std::string _msg;

public:
    void printMessage(){ std::cout << _msg << std::endl; }
};

class WidgetFactory
{
public:
    static std::unique_ptr<Widget> create(){ auto w = std::unique_ptr<Widget>(new Widget);
                                             w->_msg = "hello world!"; return w; }
};
Run Code Online (Sandbox Code Playgroud)

然后是用户:

int main(int argc, char** argv)
{
    auto w = WidgetFactory::create();
    w->printMessage();
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用私有令牌使ctor显式公开,这样我就可以使用std :: make_shared/unique.

但我不记得之前看过这种模式,所以我的问题是,这是一个好习惯吗?你介意从你的同事那里看到这样的代码吗?

提前致谢.

c++ factory friend

2
推荐指数
1
解决办法
2070
查看次数

rvalues的std :: fill_n,是否只支持按副本填写?

给予std::vectorstd::futures

std::vector<std::future<void>> futures;
Run Code Online (Sandbox Code Playgroud)

std::fill_n当我传递右值时,怎么抱怨我调用复制构造函数:

std::fill_n(std::back_inserter(futures), 10, std::async([]{ std::cout << "yo\n"; }));

error: use of deleted function future(const future&)
Run Code Online (Sandbox Code Playgroud)

我的意思是,没有fill_n收到xvalue?如果没有,为什么不呢?

c++

0
推荐指数
2
解决办法
75
查看次数