在c ++中评估默认参数在哪里?

时间:2015-06-23 04:29:59

标签: c++ parameters

如果有如下功能,

void logData(std::string data, int line=__LINE__);

是在调用函数或声明函数的位置计算的默认参数?行为是标准的,还是依赖于编译器?

2 个答案:

答案 0 :(得分:0)

你问:

  

是在调用函数或声明函数的位置计算的默认参数?行为是标准的,还是依赖于编译器?

默认参数的值将是声明函数的文件的行号。这符合标准。

来自C ++ 11标准:

  

16.8预定义的宏名称

     

...

     

_ _ LINE _ _
  当前源行的假定行号(在当前源文件中)(整数常量)。

由于__LINE__是预处理器宏,因此编译器编译的代码中没有__LINE__。取而代之的是,它将看到一个整数常量,表示文件中行的行号,该行是声明函数的文件。

答案 1 :(得分:0)

这听起来像Python程序员可能会问的一个问题,但你选择了一个有两个答案的变体。

第一部分是__LINE__,它是一个预处理器宏。顾名思义,预处理是在某些“处理”步骤之前完成的。在这种情况下,它发生在编译器尝试编译代码之前。预处理涉及将“#include”语句替换为文件的预处理内容,评估和替换宏,#define和#if语句等。

所以当编译器看到

void logData(... __LINE__)

在文件的第123行,__LINE__将替换为常量123。您可以通过使用宏来避免这种情况,例如

enum Level { DEBUG, NOTE, WARNING, ERROR };
#define FLD  __FILE__, __LINE__, DEBUG
#define FLN  __FILE__, __LINE__, NOTE
#define FLW  __FILE__, __LINE__, WARNING
#define FLE  __FILE__, __LINE__, ERROR

void log(const char* file_, size_t line_, Level level_, const char* what);
...
logData(FLD, "debug message");

关于参数“评估”的位置,请致电网站;所以你不会遇到Python的

from __future__ import print_function

def f(inlist, l=[]):
    if l:
        l.append("unexpected surprise")
    l.extend(inlist)
    return l

f([1])
print(f([2]))

http://ideone.com/GvmsL6

[1, 'unexpected surprise', 2]

在c ++中

#include <iostream>
#include <vector>
#include <string>

using strvec = std::vector<std::string>;

strvec f(strvec in, strvec out={})
{
    if (!out.empty())
        out.push_back("unexpected surprise");
    out.insert(out.end(), in.cbegin(), in.cend());
    return out;
}

int main()
{
    f({"a"});
    auto vec = f({"b"});
    for (auto& str: vec) {
        std::cout << str << "\n";
    }   
}

请参阅http://ideone.com/17ilNL