我正在编写constexpr
代码,我想在编译时检查计算值。
通常的技巧是做这样的事情:
struct ReturnValue
{
int value1;
int value2;
};
constexpr ReturnValue doTheComputation()
{
return { .value1 = 10, .value2 = 20 };
}
template< auto t > struct p;
p< doTheComputation() > foo;
这给出了:
implicit instantiation of undefined template 'p<ReturnValue{10, 20}>'
我可以看到结果的价值。
但是,这不适用于非结构化类型,例如std::string_view
、std::string
或任何类似于字符串的类型,因为这些类型不允许是 NTTP。
不起作用的示例std::string_view
: https
不起作用的示例char const *
:
即使我使用它char const[ some_large_numer ]
来确保消息适合,就像,而不是字符串,我也会得到作为模板参数列出的 ASCII 值:
implicit instantiation of undefined template 'p<ReturnValue{{115, 111, 109, 101, 32, 115, 101, 99, 114, 101, ...}}>
是否有任何技巧或窍门可以在编译时打印非结构类型的值(作为 constexpr 函数的结果)?
我已经看到了,它显然解决了这个问题(我还没有测试过),但我正在寻找 clang 的解决方案(Xcode 15 或更新版本和 LLVM 18 或更新版本的 Apple-clang)。
10
最佳答案
1
在问题评论中提出的想法的启发,我进行了更多搜索。我发现 C++26 有一种风格,static_assert
允许第二个参数是类似字符串的constexpr
计算结果()。
不幸的是,即使在 C++26 中std::format
也不是友好的( ),但我总是可以编写输出字符串类文字对象的格式化函数(根据规范,它只需要提供和函数),所以我想出了以下解决方案:constexpr
.size()
.data()
#include <string_view>
#include <string>
struct ReturnValue
{
std::string_view data;
std::string data2;
};
constexpr ReturnValue doTheComputation()
{
return { .data = "some secret message", .data2 = "owned data" };
}
constexpr std::string format( ReturnValue const & val )
{
std::string result{ val.data };
result += ", additional data: ";
result += val.data2;
return result;
}
static_assert( false, format( doTheComputation() ) );
这似乎,但在 Xcode 15.4 附带的 Apple-Clang 上还不行(我仍然需要用 Xcode 16 beta 进行测试)。
总的来说,这是一个可行的解决方案,但如果有人能提出一个可以在 Xcode 15.4 上使用的解决方案,我会更高兴。
1
-
,显然该功能不会在 Xcode 16 中实现。
–
|
return {.value1 = 10, .value2 = 20}
到return {10,20}
–
p<std::format("{}", doTheComputation())>
。–
sizeof()
或offsetof
。–
ReturnValue
很远(例如在另一个文件中),它对人类读者仍然有帮助。我更喜欢明确的定义。–
return Rectangle{.width=3, .height=4};
更清楚。我不是在谈论编写代码。return Rectangle{3,4}
–
|