On Monday, April 17, 2017 13:45:18 Dmitry via Digitalmars-d-learn wrote: > On Monday, 17 April 2017 at 10:55:30 UTC, Jonathan M Davis wrote: > > They works, but it results in a new template being instantiated > > for every call, so you really shouldn't use __FILE__ or > > __LINE__ as template arguments if you can avoid it. > > Does it matter if I anyway use template (S...) ? > And what problem with that new templates for every call? > Increases .exe size? Needs more memory (runtime? compile-time?)? > Something else?
Every time there's a new template instantiation, it's essentially copy-pasting the entire template. So, if you have the templated function auto foo(T)(T bar) { return bar; } and then call foo(5); foo(true); foo("hello"); then you get the equivalent of int foo!int(int bar) { return bar; } bool foo!bool(bool bar) { return bar; } string foo!string(string bar) { return bar; } in your program. If you have string foo(string file = __FILE__, size_t line = line)(string bar) { return bar; } and you call that function 17 times, then you get 17 separate functions. If you call it 120 times you get 120 separate functions. So, if you call the function very many times, the template bloat would be enormous. The executable will be _much_ larger and will thus take up much more space on disk and much more RAM when it's loaded into memory. In some cases, that makes sense, but it usually doesn't. > > Usually, the better way to handle it is to use runtime > > arguments, e.g. > > void error(string msg, string file = __FILE__, size_t line = > > __LINE__) > > Is possible use this with (S...)? In some cases I use many > arguments (5-10, mixed strings and numbers) and I tried to avoid > the concatenation them into string. > > What will be better? Concatenation or templates? Or maybe an > another way? The short answer is that if you're using variadic templates, you can't use default arguments. Something like auto foo(Args...)(Args args, string file = __FILE__, size_t line = __LINE__) { ... } auto result = foo("hello", 42); does not work. So, if you want to have the file and line number passed automatically with a variadic template, then you're forced to use template parameters instead of function paramaters and incur whatever bloat that goes with that. Now, that being said, surprisingly, it does look like it works to do auto foo(Args...)(Args args, string file = __FILE__, size_t line = __LINE__) { ... } auto result = foo!(string, int)("hello", 42); So, if you're okay with explicitly instantiating your variadic function template instead of having the types inferred, then it can work, but otherwise, no. Making it work would require a language enhancement, and even then, if you ever wanted to explicitly provide the file and line number arguments instead of using the default arguments, you'd almost certainly be forced to explicitly instantiate the template, since the compiler would have no other way of determining whether the file and line arguments on the end were intended to be the file and line arguments or just more variadic arguments. - Jonathan M Davis