c ++中的条件运算符错误?

pro*_*mer 2 c++ gcc conditional-operator

这些演示函数不应该是gcc中的无限循环,因为条件运算符应该只评估活动部分.

它们在visual studio 2015中正确编译,但在g ++ 6.3中给出了无限递归错误编译错误.我错过了什么?

template <int n>
constexpr int infinite_loop_error(){
   return (n)  ? infinite_loop_error<n - 1>() : 0;
}

template <int n> 
constexpr int infinite_loop_error_2(){
   if (n) return infinite_loop_error_2<n - 1>(); 
   else   return 0;
}

void main() {
  infinite_loop_error<3>();
  infinite_loop_error_2<3>();
}
Run Code Online (Sandbox Code Playgroud)

zne*_*eak 7

这是MSVC中的一个错误,您的程序不应该编译.您正在混合运行时递归和编译时递归.

虽然程序应该只在运行时评估三元表达式的一只手,但编译器仍然需要为三元表达式的双手(以及条件的两个分支if)生成代码.您的程序在代码生成期间失败,因为编译器找不到它可以停止的点.MSVC"成功",因为它过早地应用优化,侵犯了as-if规则.

您需要使用模板专门化作为停止条件:

template <int n>
constexpr int infinite_loop_error(){
   return (n)  ? infinite_loop_error<n - 1>() : 0;
}

template <>
constexpr int infinite_loop_error<0>(){
    return 0;
}

template <int n> 
constexpr int infinite_loop_error_2(){
   if (n) return infinite_loop_error_2<n - 1>(); 
   else   return 0;
}

template <> 
constexpr int infinite_loop_error_2<0>(){
   return 0;
}

int main() {
  infinite_loop_error<3>();
  infinite_loop_error_2<3>();
}
Run Code Online (Sandbox Code Playgroud)

infinite_loop_error<0>编译器使用您为其提供的定义而不是实例化将使其进一步递归的定义,而编译时递归正确停止.