List 在字符串列表上循环

List 在字符串列表上循环,list,foreach,cmake,List,Foreach,Cmake,我想循环一下以字符串形式给出的项目列表。根据CMake的要求,项目之间用分号分隔。以下 cmake_minimum_required(VERSION 2.8) FOREACH(LETTER "a;b;c") MESSAGE("<<${LETTER}>>") ENDFOREACH() 这是循环列表的推荐方法还是有更优雅的解决方案?您困惑的根源可能是CMake对带引号字符串的特殊解释 例如,以下命令可以正确地迭代字符串列表: (1) foreach(LETTER a

我想循环一下以字符串形式给出的项目列表。根据CMake的要求,项目之间用分号分隔。以下

cmake_minimum_required(VERSION 2.8)

FOREACH(LETTER "a;b;c")
  MESSAGE("<<${LETTER}>>")
ENDFOREACH()

这是循环列表的推荐方法还是有更优雅的解决方案?

您困惑的根源可能是CMake对带引号字符串的特殊解释

例如,以下命令可以正确地迭代字符串列表:

(1) foreach(LETTER a b c) [...]
(2) foreach(LETTER a;b;c) [...]
(3) set(MYLIST "a;b;c")
    foreach(LETTER ${MYLIST}) [...]
唯一不起作用的情况是

(4) foreach(LETTER "a;b;c") [...]
(1)
(2)
工作的原因在于:

无引号的参数内容由连续块中的所有文本组成 允许的或转义的字符。逃逸序列和变量 对参考文献进行评估。结果值被除以相同的值 方式列表分为多个元素。每个非空元素都被赋予 命令调用作为参数。因此,未引用的论点可能 作为零个或多个参数提供给命令调用

注意,这不同于,后者也计算转义序列和变量引用,但不进行列表扩展。这解释了
(4)
失败的原因

现在有趣的问题是为什么
(3)
仍然成功。将同时接受单值和列表值参数。事实上,在关闭
之前的所有内容或
缓存
父范围
中的一个关键字都被视为该值的一部分。因此,以下两个命令是等效的:

set(MYLIST "a;b;c")
set(MYLIST a;b;c)
在这两种情况下,
MYLIST
的值都是
a;Bc
(不带引号)

当我们现在将
${MYLIST}
扩展到另一个命令中时,您可以想象它使用
MYLIST
的值执行简单的字符串替换,即
a;Bc
。然后,生成的命令将通过带引号或不带引号的参数规则进行扩展。也就是说,以下措施将起作用:

foreach(LETTER ${MYLIST}) [...]
但这不会:

foreach(LETTER "${MYLIST}") [...]

首先,考虑如果在<代码>前缀调用中键入所有值,如<代码>前缀(n 1 2 3)< /代码>,或者如果您想扩展一个变量,如<代码>前缀(n${MyAuthNoMyListList})

虽然接受的答案在行上展开变量,使代码注入成为可能(如果变量设置在脚本之外),但在大多数情况下仍然可以使用

但对于安全循环(不展开变量),请尝试以下操作:

# My dummy data.
set (_my_list "A B C")
string (REPLACE " " ";" _my_list "${_my_list}")

# Actual looping.
foreach (current IN LISTS _my_list)

    # All done! do something with ${current}, for example:
    if (NOT current IN_LIST _my_other_list)
        message(FATAL_ERROR "_my_list has ${current} but _my_other_list does not!!")
    endif()

endforeach()
# My dummy data.
set (_my_list "A B C")
string (REPLACE " " ";" _my_list "${_my_list}")

# Actual looping.
foreach (current IN LISTS _my_list)

    # All done! do something with ${current}, for example:
    if (NOT current IN_LIST _my_other_list)
        message(FATAL_ERROR "_my_list has ${current} but _my_other_list does not!!")
    endif()

endforeach()