2012-02-28 79 views
-2

我很感兴趣,引用标准中的具体段落,而不仅仅是一般意见。这是合法的C++代码吗?

template <class T> struct wrapped 
{ 
     wrapped(const T&) {} 
}; 

template <class T> wrapped<T> wrappit(const T& x) 
{ 
     return wrapped<T>(x); 
} 

template <class T> int run_function(const T& x, bool wrapped) 
{ 
     if (wrapped) { 
       return 0; 
     } else { 
       return run_function(wrappit(x), true) + 1; 
     } 
} 

int main() 
{ 
     const int result = run_function(0.5, false); 
     return result; 
} 
+0

这应该做什么?它所做的一切就是让'main'以迂回的方式返回1。 – 2012-02-28 22:50:59

+6

是什么让你认为这是非法的C++?尽管不定式实例化深度最有可能杀死一个愚蠢的编译器?我的意思是,“int main(){}”是一个合法的C++代码吗?请给我一个关于它的标准。 – 2012-02-28 22:53:19

+1

这是一个关于“合法”一词定义的问题吗?我猜编译器会递归地将T封装在'wrapped Qwertie 2012-02-28 22:53:37

回答

4

从14.7.1(15):

的实例化中无限递归的结果是未定义的。


关于你的代码:你不能这样做静态条件语句与if。相反,你需要某种功能的办法,和部分专业化:

template <typename T, bool> struct run_function; 
template <typename T> struct run_function<T, true> 
{ 
    static int go(T const & x) { return 0; } 
}; 
template <typename T> struct run_function<T, false> 
{ 
    static int go(T const & x) 
    { return 1 + run_function<T, true>::go(wrappit(x)); } 
}; 

现在有没有更多的无限递归,因为两个分支使用不同模板,最终没有进一步实例化模板。

+0

感谢您的建议,但我需要在运行时设置布尔开关。解决这个问题的正确方法是从第一个函数调用一个不同的函数。 – 2012-02-29 09:04:10

5

符合实现可能会拒绝此代码。见标准附录B.

你的实现应该包括在其文档中的某些限制,其中包括:

  • 递归嵌套的模板实例
+1

Ben,我认为每个编译器都会因为递归嵌套实例化或者因为他们会崩溃或停留在不定式循环中而拒绝它,直到它们耗尽内存并崩溃:-D – 2012-02-28 23:06:22

+0

@Vlad:一个足够聪明的优化器可能会破坏无限递归。 – 2012-02-28 23:46:09

+0

GCC很聪明!哇噢! – 2012-02-29 00:34:20