打印编译时字符串_view



假设我有一个返回std::string_view的元函数

template<typename T>
struct type_to_string;
template <typename T>
constexpr std::string_view type_to_string_v = type_to_string<T>::value;

以及由此产生的字符串视图:

constexpr auto sv = type_to_string_v<very_complex_expression>;

有没有办法在编译时打印这个字符串的值?(即作为某些编译器错误消息或静态断言的一部分(

下面是对OP解决方案的修改,它使用gcc生成了一条可读性更强的消息。不幸的是,clang的消息可读性较差,MSVC根本不起作用(我想是由于编译器错误(。

#include <cstdlib>
#include <algorithm>
#include <string_view>
#include <utility>
template <size_t N> struct FS {             // fixed size string
char chars[N + 1] = {};
constexpr FS(const char (&str)[N + 1]) {
std::copy_n(str, N + 1, chars); 
}
};
template <size_t N> FS(const char (&str)[N])->FS<N - 1>;
template<typename T>
struct type_to_string;
template<>
struct type_to_string<int> { constexpr static auto value = "integer"; };
template <auto>
constexpr bool string_value = false;
template<FS fs>                             // size will be deduced
void compile_time_display() {
static_assert(string_value<fs>);
}
int main()
{
constexpr std::string_view sv = type_to_string<int>::value;
constexpr size_t n = sv.size();
constexpr auto indices = std::make_index_sequence<n>();
[&] <std::size_t... I>
(std::index_sequence<I...>)
{
static constexpr char text[] { (char)sv.at(I)..., 0 };
compile_time_display<text>();    // the char array will convert to FS
}(indices);
}

gcc显示的消息为:

main.cc: In instantiation of ‘void compile_time_display() 
[with FS<...auto...> fs = FS<7>{"integer"}]’
...
main.cc:26:23: note: ‘string_value<FS<7>{"integer"}>’ evaluates to false

C++没有机制";打印";编译时的任何内容。持续评估没有输入或输出机制。static_assert可以用于显示消息,但它们特别采用字符串文字。

事实证明,通过将string_view分解为一个字符列表,可以以相对简单的方式实现这一点。下面是一个完整的例子,扩展了原始问题的设置:

#include <string_view>
#include <utility>
template<typename T>
struct type_to_string;
template<>
struct type_to_string<int> { constexpr static auto value = "integer"; };
template <char... T>
constexpr bool string_value = false;
template<char... c>
void compile_time_display() {
static_assert(string_value<c...>);
}
int main() {
constexpr std::string_view sv = type_to_string<int>::value;
constexpr size_t n = sv.size();
constexpr auto indices = std::make_index_sequence<n>();
[&] <std::size_t... I>
(std::index_sequence<I...>)
{
compile_time_display<sv.at(I)...>();
}(indices);
}

流行的编译器突出显示字符串值:

$ g++ sv_to_array.cpp
sv_to_array.cpp: In instantiation of ‘void compile_time_display() [with char ...c = {'i', 'n', 't', 'e', 'g', 'e', 'r'}]’:
sv_to_array.cpp:26:36:   required from ‘main()::<lambda(std::index_sequence<I ...>)> [with long unsigned int ...I = {0, 1, 2, 3, 4, 5, 6}; std::index_sequence<I ...> = std::integer_sequence<long unsigned int, 0, 1, 2, 3, 4, 5, 6>]’
sv_to_array.cpp:27:3:   required from here
sv_to_array.cpp:15:23: error: static assertion failed
15 |         static_assert(string_value<c...>);
|                       ^~~~~~~~~~~~~~~~~~
sv_to_array.cpp:15:23: note: ‘string_value<'i', 'n', 't', 'e', 'g', 'e', 'r'>’ evaluates to false
$ clang++ sv_to_array.cpp -std=c++20
sv_to_array.cpp:15:2: error: static_assert failed due to requirement 'string_value<'i', 'n', 't', 'e', 'g', 'e', 'r'>'
static_assert(string_value<c...>);
^             ~~~~~~~~~~~~~~~~~~
sv_to_array.cpp:26:3: note: in instantiation of function template specialization 'compile_time_display<'i', 'n', 't', 'e', 'g', 'e', 'r'>' requested here
compile_time_display<sv.at(I)...>();
^
1 error generated.

最新更新