嵌套`constexpr`函数在定义之前调用常量表达式上下文

时间:2016-05-30 13:01:46

标签: c++ language-lawyer constexpr function-declaration function-definition

根据我从this answer收集的内容,如果函数尚未声明,则constexpr函数的结果不是常量表达式。让我感到惊讶的是以下代码片段:

constexpr int f();

constexpr int g() {
    return f();
}

constexpr int f() {
    return 42;
}

int main() {
    constexpr int i = g();
    return i;
}

这编译没有任何问题并且有效。正如我所料,将f的定义移至主要触发器error: 'constexpr int f()' used before its definition

我认为它有效,因为f在调用g之前已定义,因此两个调用都是常量表达式。

为什么f()g()显然是常量表达式,即使在f调用g时未定义library(dplyr) library(tidyr) library(ggplot2) library(grid) df1 <- data.frame(matrix(rnorm(50), 10, 10)) df2 <- data.frame(matrix(rnorm(30), 10, 10)) df3 <- data.frame(matrix(rnorm(20), 10, 5)) df4 <- data.frame(matrix(rnorm(70), 10, 5)) df5 <- data.frame(matrix(rnorm(110), 10, 15)) df6 <- data.frame(matrix(rnorm(70), 10, 15)) data <- list(df1, df2, df3, df4, df5, df6) all_names <- c("Mark", "Tere", "Marcus", "Heidi", "Georg", "Tieme", "Joan", "Tytus", "Julius", "Crater") for (i in seq_along(data)){ # Adding number of columns data[[i]]$n_col <- ncol(data[[i]]) # Adding the random order row names data[[i]]$id <-sample(all_names, 10) # Adding a data frame number column data[[i]] <- cbind(data[[i]], frame = i) } df <- plyr::rbind.fill(data) %>% gather(time, value, -id, -frame, -n_col) %>% filter(!is.na(value)) %>% mutate(time = gsub('X', '', time) %>% as.numeric) plot_name <- function(name){ df %>% filter(id %in% c('Heidi', 'Joan', name)) %>% ggplot() + aes(x = time, y = value, group = id, colour = id) + geom_line() + geom_point() + facet_wrap(frame ~ n_col, scales = 'free_x', nrow = 3, ncol = 2) + theme(strip.background = element_blank(), strip.text.x = element_blank()) } pdf(file = sprintf("Df_plots.pdf", df1), paper='A4r') for (name in setdiff(all_names, c('Heidi', 'Joan'))){ print(plot_name(name)) #grid.newpage() } dev.off() ?标准如何描述?

我在Coliru的GCC 6.1.0和Clang 3.8.0上测试了这个。

2 个答案:

答案 0 :(得分:0)

在使用之前没有必要定义constexpr。但是,在定义之前调用它的结果不是constexpr。因此,编译器正确地抱怨,因为您尝试使用非常量表达式初始化constexpr变量。

§5.20/ p2常量表达式[expr.const] 强调我的):

  

条件表达式e是核心常量表达式,除非   评估e,遵循抽象机的规则(1.9),   将评估以下表达式之一:

     

...

     

(2.3) - 调用未定义的constexpr函数或者   undefined constexpr构造函数;

答案 1 :(得分:0)

由T.C.联系起来。在his comment中,这取决于defect report

  

根据5.20 [expr.const] bullet 2.3,表达式是常量   表达除非(除其他原因外)评估

     
      
  • 调用未定义的constexpr函数或未定义的constexpr构造函数;
  •   
     

这没有解决constexpr的问题。   必须定义函数。意图,以允许   相互递归的constexpr函数,函数必须是   在最终评估之前定义的最终结果   调用,但这没有明确说明。

这清楚地表明,只要在调用f之前定义了g,该示例就是格式良好的,并且确实应该按预期工作。