How to drive C#, C++ or Java compiler to compute 1+2+3+...+1000 at compile time?(如何在编译时驱动 C#、C++ 或 Java 编译器计算 1+2+3+...+1000?)
问题描述
在最近的一次采访中,我被问到一个非常奇怪的问题.面试官问我如何仅使用编译器功能计算 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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何在编译时驱动 C#、C++ 或 Java 编译器计算 1+2+3+...+1000?
基础教程推荐
- Java:带有char数组的println给出乱码 2022-01-01
- 设置 bean 时出现 Nullpointerexception 2022-01-01
- 如何使用 Java 创建 X509 证书? 2022-01-01
- 减少 JVM 暂停时间 >1 秒使用 UseConcMarkSweepGC 2022-01-01
- 降序排序:Java Map 2022-01-01
- Java Keytool 导入证书后出错,"keytool error: java.io.FileNotFoundException &拒绝访问" 2022-01-01
- 在 Libgdx 中处理屏幕的正确方法 2022-01-01
- 无法使用修饰符“public final"访问 java.util.Ha 2022-01-01
- FirebaseListAdapter 不推送聊天应用程序的单个项目 - Firebase-Ui 3.1 2022-01-01
- “未找到匹配项"使用 matcher 的 group 方法时 2022-01-01