简体   繁体   English

std :: function分配在Visual C ++ 2015 Win32应用程序中不起作用

[英]std::function assignment has no effect in Visual C++ 2015 Win32 Application

Here's my scenario: 这是我的情况:

main.cpp main.cpp

#include <Windows.h>
#include <functional>

std::function<void()> OnPrepare;

int WINAPI WinMain(HINSTANCE inst, HINSTANCE preInst, TCHAR*, int) {
    if (OnPrepare) {
        OnPrepare();
    }

    return 0;
}

other.cpp other.cpp

#define _AFXDLL
#include <afx.h>  // TRACE
#include <functional>

extern std::function<void()> OnPrepare;

class Init {
public:
    Init() {
        OnPrepare = []() {
            TRACE("hello, world!\n");
        };
    }
};

Init g_init;

This code does not work in a Win32 application, but works well in a Console application. 此代码在Win32应用程序中不起作用,但在控制台应用程序中则很好。 I don't know why. 我不知道为什么 Can anyone point out what's wrong with my code? 谁能指出我的代码出了什么问题? If I can't do it like this, is there a better way? 如果我不能这样做,还有更好的方法吗?

EDIT: 编辑:

OnPrepare is always null in a Win32 application, so no "hello, world" will appear. 在Win32应用程序中, OnPrepare始终为null,因此不会出现"hello, world"

The code for constructing g_init modifies OnPrepare . 构造g_init的代码修改了OnPrepare This is, of course, only legal if OnPrepare has already been constructed. 当然,只有在已经构建OnPrepare情况下,这才是合法的。 But what if g_init is constructed before OnPrepare ? 但是,如果在OnPrepare之前构造了g_init呢? Then you'll be modifying an object that hasn't been constructed yet and then later constructing an object you've already modified. 然后,您将修改尚未构造的对象,然后再构造已经修改的对象。 Ouch. 哎哟。 Doing real work in the constructors of static objects is never a good idea. 在静态对象的构造函数中进行实际工作从来都不是一个好主意。

It's not clear what your outer problem is, but this code isn't a good way to solve it. 目前尚不清楚您的外部问题是什么,但是此代码不是解决此问题的好方法。 An ugly workaround is to replace your global std::function with a global function that returns a reference to a function static std::function and use that. 一个丑陋的解决方法是将全局std::function替换为返回对静态static std::function的引用的全局std::function并使用该全局函数。 That ensures the object is constructed before being assigned to. 这样可以确保在分配对象之前构造对象。

std::function<void()>& getOnPrepare()
{
    static std::function<void()> OnPrepare;
    return OnPrepare;
}

Then the constructor of Init can call getOnPrepare , ensuring that OnPrepare is constructed before it's assigned to: 然后, Init的构造函数可以调用getOnPrepare ,确保在将OnPrepare分配给以下对象之前对其进行构造:

Init() {
    getOnPrepare() = []() {
        TRACE("hello, world!\n");
    };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM