问题描述
在最近的一次采访中,我被问到一个非常奇怪的问题.面试官问我如何仅使用编译器功能计算 1+2+3+...+1000.这意味着我不能编写程序并执行它,但我应该只编写一个程序,它可以驱动编译器在编译时计算这个总和,并在编译完成时打印结果.作为提示,他告诉我我可以使用编译器的泛型和预处理器特性.可以使用 C++、C# 或 Java 编译器.有什么想法???
In a recent interview, I was asked a really strange question. The interviewer asked me how can I compute 1+2+3+...+1000 just using compiler features. This means that I am not allowed to write a program and execute it, but I should just write a program that could drive the compiler to compute this sum while compilation and print the result when compilation completes. As a hint, he told me that I may use generics and pre-processor features of the compiler. It is possible to use C++, C# or Java compiler. Any ideas???
这个问题与在没有任何循环的情况下计算总和无关在这里询问.此外,需要注意的是,总和应该在编译期间计算.使用 C++ 编译器指令仅打印结果是不可接受的.
This question is not related to computing the sum without any loops asked here. In addition, It should be noted that the sum SHOULD be calculated during compilation. Printing just the result using C++ compiler directives is not acceptable.
阅读有关已发布答案的更多信息,我发现使用 C++ 模板在编译期间解决问题称为元编程.这是 Erwin Unruh 博士在标准化 C++ 语言的过程中偶然发现的一种技术.您可以在 元编程的 wiki 页面上阅读有关此主题的更多信息.似乎可以使用 Java 注释在 Java 中编写程序.您可以看看下面的 maress's 答案.
Reading more about the posted answers, I found that solving problems during compilation using C++ templates is called metaprogramming. This is a technique that was discovered accidentally by Dr. Erwin Unruh, during the process of standardizing the C++ language. You may read more about this topic on wiki page of meta-programming. It seems that it is possible to write the program in Java using java annotations. You may take a look at maress's answer below.
一本关于 C++ 元编程的好书是 this一个.有兴趣的值得一看.
A nice book about meta-programming in C++ is this one. Worth to take a look if interested.
一个有用的 C++ 元编程库是 Boost 的 MPL 此链接.
A useful C++ meta-programming library is Boost's MPL this link.
推荐答案
更新 现在提高了递归深度!适用于 MSVC10 和 GCC,无需增加深度.:)
Updated Now with improved recursion depth! Works on MSVC10 and GCC without increased depth. :)
简单的编译时递归+加法:
Simple compile-time recursion + addition:
template<unsigned Cur, unsigned Goal>
struct adder{
static unsigned const sub_goal = (Cur + Goal) / 2;
static unsigned const tmp = adder<Cur, sub_goal>::value;
static unsigned const value = tmp + adder<sub_goal+1, Goal>::value;
};
template<unsigned Goal>
struct adder<Goal, Goal>{
static unsigned const value = Goal;
};
测试代码:
template<unsigned Start>
struct sum_from{
template<unsigned Goal>
struct to{
template<unsigned N>
struct equals;
typedef equals<adder<Start, Goal>::value> result;
};
};
int main(){
sum_from<1>::to<1000>::result();
}
GCC 的输出:
错误:‘struct sum_from<1u>::to<1000u>::equals<500500u>’的声明
error: declaration of ‘struct sum_from<1u>::to<1000u>::equals<500500u>’
Ideone 上的实时示例.
MSVC10 的输出:
Output for MSVC10:
error C2514: 'sum_from<Start>::to<Goal>::equals<Result>' : class has no constructors
with
[
Start=1,
Goal=1000,
Result=500500
]
这篇关于如何在编译时驱动 C#、C++ 或 Java 编译器计算 1+2+3+...+1000?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!