在最近的一次采访中,我被问到一个非常奇怪的问题.面试官问我如何使用编译器功能计算1 + 2 + 3 + ... + 1000.这意味着我不允许编写程序并执行它,但我应该编写一个程序,可以驱动编译器在编译时计算这个总和,并在编译完成时打印结果.作为提示,他告诉我,我可能会使用编译器的泛型和预处理器功能.可以使用C++,C#或Java编译器.有任何想法吗???
这个问题与计算总和无关,这里没有任何循环问题.此外,应该注意,总和应该在编译期间计算.不能使用C++编译器指令打印结果.
阅读更多关于发布的答案,我发现在使用C++模板编译期间解决问题称为元编程.这是Erwin Unruh博士在标准化C++语言过程中偶然发现的一种技术.您可以在元编程的wiki页面上阅读有关此主题的更多信息.似乎可以使用Java注释在Java中编写程序.您可以在下面看看maress的答案.
关于C++的元编程一个很好的书是这一个.如果感兴趣,值得一看.
一个有用的C++元编程库是Boost的MPL 这个链接.
这是我正在尝试做的简化版本
enum First
{
a,
b,
c,
nbElementFirstEnum,
};
enum Second
{
a,
b,
c,
nbElementSecondEnum,
};
static_assert(
First::nbElementFirstEnum == Second::nbElementSecondEnum,
"Not the same number of element in the enums.");
/*static_assert(
First::nbElementFirstEnum == Second::nbElementSecondEnum,
"Not the same number of element in the enums." + First::nbElementFirstEnum + " " + Second::nbElementSecondEnum);*/
Run Code Online (Sandbox Code Playgroud)
但是我希望能够在断言消息中打印First :: nbElementFirstEnum和Second :: nbElementSecondEnum的值(就像在注释版本中显然不起作用).我尝试使用"#"进行宏连接.我还尝试使用可变参数模板,使用%10检索每个数字并将"0"字符添加到检索到的值,但我得到的只是constexpr char [].
所以我的问题是如何让我的枚举值以字符串文字打印.
可能重复:
最有趣的话题是: 在编译时打印sizeof(T) 但是我不希望有警告或退出代码来知道值.
在我之前的问题中,我想使用static_assert将模板参数限制为特定的子类型.问题得到了解答,获得批准的代码如下:
template <typename T>
struct X {
static_assert(std::is_base_of<Y,T>::value,"T must be derived from Y!");
};
Run Code Online (Sandbox Code Playgroud)
现在,我想让错误信息更简洁.即,我想说明哪种类型违反了这种约束.例如,如果类A不是从Y某个实例派生出来的X<A>,那么错误消息应该打印"类型参数必须从Y派生,但A不是".
这是用标准库实现的吗?
我看到两个挑战:
问题
不构建以下内容,因为该消息不是字符串文字.
template<typename T>
struct Foo
{
Foo()
{
static_assert( is_pod<T>::value, typeid(T).name() );
}
};
Run Code Online (Sandbox Code Playgroud)
最终,如果我尝试编译,我想要一个失败的消息,如"Bar必须是pod-type" Foo<Bar> fb;.
是否可以在编译期间构建此字符串,如static_assert?