จะใช้อาร์กิวเมนต์มาโครเป็นสตริงลิเทอรัลได้อย่างไร


92

ฉันกำลังพยายามหาวิธีเขียนมาโครที่จะส่งทั้งการแทนค่าตัวอักษรสตริงของชื่อตัวแปรพร้อมกับตัวแปรในฟังก์ชัน

ตัวอย่างเช่นให้ฟังก์ชันต่อไปนี้

void do_something(string name, int val)
{
   cout << name << ": " << val << endl;
}

ฉันต้องการเขียนมาโครดังนั้นฉันจึงสามารถทำได้:

int my_val = 5;
CALL_DO_SOMETHING(my_val);

ซึ่งจะพิมพ์ออกมา: my_val: 5

ฉันลองทำสิ่งต่อไปนี้:

#define CALL_DO_SOMETHING(VAR) do_something("VAR", VAR);

อย่างไรก็ตามอย่างที่คุณอาจเดาได้ว่า VAR ภายในเครื่องหมายคำพูดจะไม่ถูกแทนที่ แต่จะถูกส่งผ่านเป็นเพียงสตริง "VAR" ดังนั้นฉันต้องการทราบว่ามีวิธีที่จะทำให้อาร์กิวเมนต์มาโครกลายเป็นสตริงลิเทอรัลได้หรือไม่


คุณกำลังพยายามใช้สิ่งนี้อย่างไร?
chris

คำตอบ:



31

คุณต้องการใช้ตัวดำเนินการ stringizing:

#define STRING(s) #s

int main()
{
    const char * cstr = STRING(abc); //cstr == "abc"
}

11

บางทีคุณอาจลองวิธีนี้:

#define QUANTIDISCHI 6
#define QUDI(x) #x
#define QUdi(x) QUDI(x)
. . . 
. . .
unsigned char TheNumber[] = "QUANTIDISCHI = " QUdi(QUANTIDISCHI) "\n";

คำถามนี้ตอบคำถามอย่างไรหรือมีประโยชน์อย่างไร
jirigracik

2
@jirigracik - อนุญาตให้นำเสนอสตริงของการขยายมาโครได้เช่นกันซึ่งแตกต่างจากคำตอบอื่น ๆ
grepcake

4
ฉันคิดว่ามันจะมีประโยชน์ในการอธิบายว่าทำไมการมีเพียงแค่QUDI(x)นั้นไม่เพียงพอ
LRDPRDX

นี่คือสิ่งที่ฉันกำลังมองหา คำอธิบายว่าเหตุใดจึงใช้งานได้ดี แต่มันช่วยแก้ปัญหาของฉันได้ (ซึ่งคำตอบอื่นไม่มี)
GMc

8
#define NAME(x) printf("Hello " #x);
main(){
    NAME(Ian)
}
//will print: Hello Ian

ฉันไม่แน่ใจทั้งหมด แต่ดูเหมือนว่า"Hello" #x"(และ#x "Hello") ทำให้สตริงติดกันโดยไม่มีช่องว่างซึ่งเป็นสิ่งที่ต้องการในบางกรณีดังนั้นนี่จึงเป็นคำตอบที่ค่อนข้างดี
Smar

1
@Smar ตรวจสอบให้แน่ใจว่าคุณเว้นวรรคหลังสตริงคงที่สวัสดี: "Hello " #x
แจ็ค

โอเคฉันคิดอย่างนั้นคุณควรแก้ไขคำตอบของคุณด้วยเนื่องจากเป็นข้อมูลที่มีค่า :)
Smar
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.