由于字符串字面量是左值,因此可以对它们进行 const 引用,可以在三元组中使用。
// You need to manually specify the size
const char (&foo)[6] = bar ? "lorem" : "ipsum";
// Or (In C++11)
auto foo = bar ? "lorem" : "ipsum";
auto 的行为完全相同(除非您必须指定大小)。
如果你想为不同长度的字符串做这件事,不幸的是,“bool ? const char[x] : const char[y]”只有在它们具有相同大小的情况下才会是一个数组类型(否则它们都会衰减为指针,并且表达式的类型为@987654324 @)。要解决这个问题,您必须手动用\0 字符填充字符串(现在您不能使用sizeof(foo) - 1 来获取大小,您必须使用strlen(foo))。
例如,而不是:
auto foo = bar ? "abc" : "defg"; // foo is a const char*
你必须这样做:
auto foo = bar ? "abc\0" : "defg"; // foo is const char(&)[5]
// Note that if `bar` is true, foo is `{'a', 'b', 'c', '\0', '\0'}`
在您必须这样做之前,请考虑如果您将变量设置为const char * const,您的编译器很可能会将它们优化为与const char[] 完全相同,如果它们也可能相同如果您不更改值,则只有 const char *(最后没有 const)。
为了不意外地得到一个指针,如果你这样做了很快就会失败,我会使用一个辅助函数:
#include <cstddef>
template<std::size_t size, std::size_t other_size = size>
constexpr auto conditional(bool condition, const char(&true_case)[size], const char(&false_case)[other_size]) noexcept -> const char(&)[size] {
static_assert(size == other_size, "Cannot have a c-string conditional with c-strings of different sizes");
return condition ? true_case : false_case;
}
// Usage:
auto foo = conditional(bar, "lorem", "ipsum");
如果bar 是编译时常量,您可以根据bar 的值更改foo 的类型。例如:
#include <cstddef>
template<bool condition, std::size_t true_size, std::size_t false_size>
constexpr auto conditional(const char(&true_case)[true_size], const char(&false_case)[false_size]) -> typename std::enable_if<condition, const char(&)[true_size]>::type {
return true_case;
}
template<bool condition, std::size_t true_size, std::size_t false_size>
constexpr auto conditional(const char(&true_case)[true_size], const char(&false_case)[false_size]) -> typename std::enable_if<!condition, const char(&)[false_size]>::type {
return false_case;
}
// Or with C++17 constexpr if
template<bool condition, std::size_t true_size, std::size_t false_size>
constexpr auto conditional(const char(&true_case)[true_size], const char(&false_case)[false_size]) -> const char(&)[condition ? true_size : false_size] {
if constexpr (condition) {
return true_case;
} else {
return false_case;
}
}
// Usage:
auto foo = conditional<bar>("dolor", "sit");