使用lambda时出现意外的宏值

Unexpected macro value when lambda is used

本文关键字:意外 lambda 使用      更新时间:2023-10-16

假设我有3个类;主舱、头等舱和二等舱。

在类First和类Second中,我定义了一个MACRO(名称-CLASS_NAME),宏的目的是在每个类中,我将宏重新定义为className或其他任何东西,以便在其函数中使用该宏。

代码的结构如下

  • Class First、Second和Main都有宏CLASS_NAME类名(例如,"first"、"second"answers"main")作为值
  • Class Second包含First并覆盖此宏值和另外声明了另一个宏PRINT_CLASS_NAME打印CCD_ 4宏
  • Class First没有这个PRINT_CLASS_NAME宏,所以我有声明了一个函数指针,并使用λ
  • Class Main包括First和Second,并重新定义了宏CLASS_NAME。要检查输出,请参阅Main.cpp文件

第一类-头文件

#pragma once
#include <iostream>
#include <functional>
#undef CLASS_NAME 
#define CLASS_NAME "first"
class First
{
public:
    First();
    ~First();
    // simple class that prints the value of CLASS_NAME
    void printClassName();
    // sets the function pointer
    void setPrintClassName(std::function<void()> inFunctionPointer);
    // The function pointer that holds the lambda to show CLASS_NAME's value
    std::function<void()> mPrintClassFromSecond;
};

第一类-源文件

#include "First.h"
First::First()
{
    std::cout << "Class First : Constructor" << "n";
}
First::~First()
{
}
void First::printClassName()
{
    std::cout << "Class name from function : " << CLASS_NAME << "n";
}
void First::setPrintClassName(std::function<void()> inFunctionPointer)
{
    mPrintClassFromSecond = inFunctionPointer;
}

第二类-头文件

#pragma once
#include "First.h"
#include <functional>
#undef CLASS_NAME
#define CLASS_NAME "second"
#define PRINT_CLASS_NAME std::cout << "Class name from Macros: " << CLASS_NAME << "n"
class Second
{
public:
    Second();
    ~Second();
};

第二类-源文件

#include "Second.h"
Second::Second()
{
    std::cout << "Class Second : Constructor" << "n";
    PRINT_CLASS_NAME;
}
Second::~Second()
{
}

主要.cpp

// MacrosWithFunctionPointerProblem.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
// after including First.h the CLASS_NAME macro value for this class is "first"
#include "First.h"
// after including Second.h the CLASS_NAME macro value for this class is "second"
#include "Second.h"
// after this the CLASS_NAME macro value for this class is "main"
#undef CLASS_NAME
#define CLASS_NAME "main"
int main()
{
    First _first;
    // outputs CLASS_NAME value "first" which is expected
    _first.printClassName();
    // sets lambda to use macro PRINT_CLASS_NAME
    _first.setPrintClassName([](){ PRINT_CLASS_NAME; });
    // outputs CLASS_NAME value "main" which was not expected by me
    _first.mPrintClassFromSecond();
    // outputs CLASS_NAME value "first" which is expected
    Second _second;
    std::getchar();
    return 0;
}

输出:

Class First : Constructor
Class name from function : first
Class name from Macros: main
Class Second : Constructor
Class name from Macros: second

问题:为什么宏CLASS_NAME的值是"main"而不是"first"。如何避免将"main"作为CLASS_NAME的值,而将"first"作为值?

附言:我尽量减少这个问题,所以如果我留下了任何可能有助于你更好地理解这个问题的重要细节,请在评论中询问。

MACRO是没有范围的文本替换,因此在中

_first.setPrintClassName([](){ PRINT_CLASS_NAME; });

PRINT_CLASS_NAME变为std::cout << "Class name from Macros: " << CLASS_NAME << "n"

并且CCD_ 11在这里被(重新)定义为CCD_。