简体   繁体   中英

How do I use __FILE__ and __LINE__ as default parameters in a constructor in c++?

I'm trying to use the __FILE__ and __LINE__ macros in a constructor as default parameters, but I can't seem to get the macros to use the right files. They keep expanding from my header file.

In more detail: I'd like to have the file and line number from where an object is instantiated as members of my class. But I don't want to have to go and put the parameters in by hand every time I want to use the objects. I know there's a way to do this, but I can't for the life of me figure it out. What I'm currently doing is the following:

In my header file:

mnNumber( float x, const char* filename = __FILE__, int linenumber = __LINE__ ): 
          value( x ), mFileName( filename ), mFunctionName( nullptr ), mLineNumber(     linenumber ), mID( 0 )

But, FILE and LINE get expanded as if they're from my header file, not the actual location I use the mnNumber.

To answer the question of why I would like to do this, I want to have the code read it's own codepage. The particular values that I use are being registered in a manager, and their value is allowed to be edited by the end user. When the end user is done editing the value, the value is written back into the code page. So, I need to know where the value came from. I also allow the end user to say that they'll never need to edit this value again, and when they click that button, the value is converted from an mnNumber back into a float, and the type on the codepage is rewritten as a float. Or, will be...hopefully.

Any advice for me?

You can do this with the preprocessor. Create a macro which expands to __LINE__ and use it:

struct S {
  S(int line, const std::string& file) :
    line(line), file(file) {
  }
  std::string file;
  int line;
};

#define SCons() S(__LINE__, __FILE__)

int main () {

  S s1 = SCons();
  S s2 = SCons();
  std::cout << s1.line << "\n";
  std::cout << s2.line << "\n";
}       

你不能这样做 - 这两个宏在遇到它们时被预处理器代替,所以它们将被交换到头文件名和亚麻。

The OP wrote in an edit:

It wasn't easy, but R. Martinho Fernandes set me on the right path. And I don't think it's threadsafe, but it works so far.

What I wanted was the ability to track and update floats just by changing the type to mnFloat. And I set up a define that calls a function in my manager to add the file, line, and function names, then changes the float to my special type. Inside the manager they're all linked together with an ID. When I call the register function, I create an object internally that I store. On the same line my special type is also created, and it registers itself with the manager. Both objects use the same kind of ID system (ID's get generated by copying from a static number that I increment each time a new object is created). Since they appear on the same code page, the ID's are always the same, and never get out of sync. Assuming I don't go multithreaded, I suppose. It feels like cheating, but it works :)

Here's how it works. I take this:

 float test = 0.5; 

And I change it to this:

 mnFloat test = 0.5; 

In my header file, mnFloat is defined like so:

 #define mnFloat myManager::getInstance()->register(__FILE__,__FUNCTION__,__LINE__);mnNumber 

So, the codepage changes to two instructions on that line, and the line number doesn't increment. And it works!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM