我正在使用宏根据模式确定变量的实类型,并且遇到了一些我不理解的奇怪的宏错误:
a.cpp:15:4: error: '#' is not followed by a macro parameter
#define USING_INTEGER\
^
a.cpp:15:11: error: unknown type name 'USING_INTEGER'
#define USING_INTEGER\
^
a.cpp:16:2: error: expected unqualified-id
else if (matchRegex(DOUBLE_REGEX, val))\
^
3 errors generated.
为什么会这样呢?我不知道,如果您知道原因,请提供一些帮助。#include "example_3.cpp"
#include <regex>
std::string INT_REGEX = "^[-+]?\\d+$",
DOUBLE_REGEX = "^[-+]?\\d+\\.\\d?$",
BOOLEAN_REGEX = "^(true|false)$";
bool matchRegex(std::string pattern, std::string inputString) {
std::regex expression(pattern);
return std::regex_match(inputString, expression);
}
#define determineType(var)\
if (matchRegex(INT_REGEX, val))\
#define USING_INTEGER\
else if (matchRegex(DOUBLE_REGEX, val))\
#define USING_DOUBLE\
else if (matchRegex(BOOLEAN_REGEX, val))\
#define USING_BOOL\
else\
#define USING_RAW
最佳答案
据我了解OP的问题的动机,目的是:
变量类型必须在编译时定义。
(这是称为static type checking的C++语言核心概念之一。
在运行时没有机会定义变量的类型。)
因此,必须在源代码中同时定义所有应支持的类型。
由于输入项可能始终最多具有这些类型中的一种,因此值的存储可以考虑到这一点。
在C语言中,会想到union,但是C++提供了更好的东西:std::variant。
将使用所有受支持的类型定义该变体,但实例将始终存储其中之一的值。在分配中根据右侧选择类型。
一个实例来证明这一点:
#include <iostream>
#include <sstream>
#include <string>
#include <variant>
// an error type
struct None { std::string text; };
// a value what can represent one of all supported types
typedef std::variant<bool, int, double, std::string, None> Value;
// reads a value from a text determining its type
Value readInput(const std::string &text)
{
// check for int
{ std::istringstream in(text); int value;
if (in >> value && in.tellg() == -1) {
return Value(value);
}
}
// check for floating point
{ std::istringstream in(text); double value;
if (in >> value && in.tellg() == -1) {
return Value(value);
}
}
// check for bool
if (text == "true") return Value(true);
if (text == "false") return Value(false);
// check for (quoted) string
if (text.size() >= 2
&& ((text.front() == '"' && text.back() == '"')
|| (text.front() == '\'' && text.back() == '\''))) {
return Value(text.substr(1, text.size() - 2));
}
// ERROR
return Value(None{ text });
}
// prints the value (considering the current type)
void print(const Value &value)
{
switch (value.index()) {
case 0: std::cout << "bool: " << std::boolalpha << std::get<bool>(value); break;
case 1: std::cout << "int: " << std::get<int>(value); break;
case 2: std::cout << "double: " << std::get<double>(value); break;
case 3: std::cout << "string: '" << std::get<std::string>(value) << '\''; break;
case 4: std::cout << "ERROR! text: '" << std::get<None>(value).text << '\''; break;
default: std::cout << "Value not initialized.";
}
}
int main()
{
const std::string tests[] = {
"true", // bool
"false", // bool
"123", // int
"123.17", // double
"0", // int
"0.0", // double
"'text'", // string
"''", // string
"something that doesn't match any type" // ERROR
};
for (const std::string &test : tests) {
std::cout << "Test \"" << test << "\"\n";
const Value value = readInput(test);
std::cout << "Got: ";
print(value);
std::cout << '\n';
}
}
输出:Test "true"
Got: bool: true
Test "false"
Got: bool: false
Test "123"
Got: int: 123
Test "123.17"
Got: double: 123.17
Test "0"
Got: int: 0
Test "0.0"
Got: double: 0
Test "'text'"
Got: string: 'text'
Test "''"
Got: string: ''
Test "something that doesn't match any type"
Got: ERROR! text: 'something that doesn't match any type'
Live Demo on coliru关于c++ - 类似于函数的宏不接受嵌套的#define,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63608967/