constexpr函数及其参数

时间:2018-04-28 14:29:47

标签: c++ constexpr

constexpr int hello(int j) {
    return j * 12;
}

constexpr int bye(int j = 6) {
    return j * 12;
}

int main() {
    int i = 6;
    constexpr int a1 = hello(i); //error
    constexpr int a2 = hello(6); //ok
    constexpr int a3 = hello(int(6)); //ok
    constexpr int a4 = bye(); //ok
    constexpr int a5 = bye(i); //error
    constexpr int a6 = bye(6); //ok
    return 0;
}

hellow(i)hello(6)之间的区别是什么?我认为一个是int j = i;而j不是constexpr,而另一个是int j = 6而j仍然不是constexpr,两个j都是int类型。
int * literal!= constexpr ,因此返回类型不是constexpr。

我从书中的一个例子得到了上述结论:
int staff_size = 27; //staff_size is not a const expression

  

虽然从文字初始化staff_size,但它不是常量表达式   因为它是一个普通的int,而不是一个const int。

此外,我注意到hello(int(6))也可以正常工作,""是什么"这里?

此外,bye()有效,而hello(i)没有,两个参数都在函数内初始化,只有一个具有默认值,这里的重点是什么?

非常困惑,希望有人能解释一下:D

PS:无意想出更好的标题,对不起

2 个答案:

答案 0 :(得分:3)

hello(6)hello(i)之间的区别在于6中的hello(6)constexpr函数参数,而i中的hello(i) int是常规i参数。

如果您将constexpr int i = 6;声明为hello(i),则hello(int(6))将编译并执行。

6中,你要将整数文字hello(int(6))转换为int。这是一项冗余操作。 hello(6)bye()具有相似(如果不相同)的行为。

j = 6有效,因为函数参数使用默认参数(constexpr int bye(int j = 6);中的constexpr)。默认的初始化参数在编译时是已知的,因此,根据定义是public static string SelectedLanguage { get { return Settings.AppSettings.GetValueOrDefault(StringConstants.SelectedLanguage, SelectedLanguageDefault); } set { Settings.AppSettings.AddOrUpdateValue(StringConstants.SelectedLanguage, value); } } public static bool FirstRun { get { return Settings.AppSettings.GetValueOrDefault(StringConstants.FirstRun, FirstRunDefault); } set { Settings.AppSettings.AddOrUpdateValue(StringConstants.FirstRun, value); } } public static int LatestUpdateVersion { get { return Settings.AppSettings.GetValueOrDefault(StringConstants.LatestUpdateVersion, LatestUpdateVersionDefault); } set { Settings.AppSettings.AddOrUpdateValue(StringConstants.LatestUpdateVersion, value); } } public static string LatestUpdateVersionDate { get { return Settings.AppSettings.GetValueOrDefault(StringConstants.LatestUpdateVersionDate, LatestUpdateVersionDateDefault); } set { Settings.AppSettings.AddOrUpdateValue(StringConstants.LatestUpdateVersionDate, value); } }

答案 1 :(得分:1)

这里要注意的是编译器"验证"代码,它没有"读"它

编译器期望constexpr的所有部分在编译时都是已知的有效常量。因此,虽然您和我知道,从阅读代码开始,i的值永远不会改变,但编译器并不知道"除非你声明i是常数。就它而言,您可以在某处执行其他代码来更改i

的值

在没有i的情况下调用函数的所有情况下,编译器毫无疑问地知道j的值是一个常量整数,值为{{ 1}},(注意:6int(6)}相同。