由于字符串文字是左值,因此您可以对它们进行 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]
的是,如果它们具有相同的大小,“”只会是数组类型(否则它们都会衰减为指针,并且表达式将是 type const char*
)。为了解决这个问题,您必须手动用\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
是编译时常量,您可以foo
根据 的值更改 的类型bar
。例如:
#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");