Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C11/C++;11宏将常量字符串与文字整数相关联 我已经有一个大的C++源代码集,其中包含用这种方式写的记录器函数的调用: LogIx(_S("This is my msg"));_C++_String_C++11_Enums - Fatal编程技术网

C11/C++;11宏将常量字符串与文字整数相关联 我已经有一个大的C++源代码集,其中包含用这种方式写的记录器函数的调用: LogIx(_S("This is my msg"));

C11/C++;11宏将常量字符串与文字整数相关联 我已经有一个大的C++源代码集,其中包含用这种方式写的记录器函数的调用: LogIx(_S("This is my msg"));,c++,string,c++11,enums,C++,String,C++11,Enums,其中: #define _S(a) (#a) 它可以工作,但我的客户希望在生产中使用一个不容易理解的记录器(我不太同意,但无论如何…)。源代码库非常大,因此我的想法是尽可能少地修改,并将一个数字(索引)与每条消息关联,并将所有消息放在一个表中,以便该数字将成为表中消息的索引 第一个想法(有效)是找到所有的_S(…)消息,从源中提取它们,并用它们的等价物填充一个枚举,然后用enum标记更改每个_S()中的参数。当然,将来添加其他消息并不容易出错,也不是很好的想法 因此,我正在考虑使用预处理器的

其中:

#define _S(a)  (#a)
它可以工作,但我的客户希望在生产中使用一个不容易理解的记录器(我不太同意,但无论如何…)。源代码库非常大,因此我的想法是尽可能少地修改,并将一个数字(索引)与每条消息关联,并将所有消息放在一个表中,以便该数字将成为表中消息的索引

第一个想法(有效)是找到所有的_S(…)消息,从源中提取它们,并用它们的等价物填充一个枚举,然后用enum标记更改每个_S()中的参数。当然,将来添加其他消息并不容易出错,也不是很好的想法

因此,我正在考虑使用预处理器的另一种解决方案,但似乎不可能在#define中使用带引号的字符串

这段C++源代码不工作,但显示我想做什么:

#define _V(a)  (#a)

const std::array<string, 3> s_logStrings = {
      _V("This is my msg"),
      _V("Param %s is: %d"),
      _V("Reset msg")
};

#define _S("This is my msg")   0
#define _S("Param %s is: %d")  1
#define _S("Reset msg")        2

int Log(size_t msgIndex)
{
   cout << s_logStrings.at(LogIx(msgIndex));
}

int main(void)
{
   std::cout << "Begin test" << std::endl;
   Log(_S("This is my msg"));
   std::cout << "End test" << std::endl;

   return 0;
}

#define _V(a)  (#a)

const std::array<string, 3> s_logStrings = {
      _V("This is my msg"),
      _V("Param %s is: %d"),
      _V("Reset msg")
};

#define _S(a) // ???? this is the problem... how define this macro?
// also a constexpr could be a good solution, the point is to don't
// add a function or a <map>

#define _S("This is my msg")   0
#define _S("Param %s is: %d")  1
#define _S("Reset msg")        2

int Log(size_t msgIndex)
{
   cout << s_logStrings.at(msgIndex);
}

int main(void)
{
   std::cout << "Begin test" << std::endl;
   Log(_S("This is my msg"));
   std::cout << "End test" << std::endl;

   return 0;
}
定义V(a)(a) 常量std::数组s_日志字符串={ _V(“这是我的味精”), _V(“参数%s为:%d”), _V(“重置消息”) }; #定义_S(“这是我的消息”)0 #定义(参数%S为:%d)1 #定义(“重置消息”)2 整数日志(大小\u t msgIndex) {
通过将文本转换为字符序列,可以, 你可以这样做:

template <char ... > struct char_sequence {};

// use gnu extension :/
template<class CharT, CharT... cs>
char_sequence<cs...> operator ""_seq(){
    return {};
}

template <class T, class Tuple>
struct index_in_tuple;

template <class T, class... Types>
struct index_in_tuple<T, std::tuple<T, Types...>> {
    static const std::size_t value = 0;
};

template <class T, class U, class... Types>
struct index_in_tuple<T, std::tuple<U, Types...>> {
    static const std::size_t value = 1 + index_in_tuple<T, std::tuple<Types...>>::value;
};

using MyMessagesTuple = decltype(std::make_tuple(
    "This is my msg"_seq,
    "Param %s is: %d"_seq,
    "Reset msg"_seq
));


#define _S(a)  (index_in_tuple<decltype(a##_seq), MyMessagesTuple>::value)

int main() {
    auto foo = _S("Reset msg");
    std::cout << foo << std::endl;
}
模板结构字符序列{};
//使用gnu扩展:/
模板
字符序列运算符“”\u seq(){
返回{};
}
模板
元组中的结构索引;
模板
元组中的结构索引{
静态常数std::size\u t值=0;
};
模板
元组中的结构索引{
静态常量std::size\u t value=1+元组中的索引\u::value;
};
使用MyMessagesTuple=decltype(std::make_tuple)(
“这是我的味精”\u seq,
“参数%s为:%d”\u seq,
“重置消息”_seq
));
#定义_S(a)(在_tuple::value中索引_)
int main(){
自动foo=_S(“重置消息”);

std::请注意,以下划线开头,后跟大写字母(
\u S
\u V
)的名称以及包含两个连续下划线的名称将保留给实现。不要使用它们。