source_location::current() оценивается как аргумент шаблона без типа по умолчанию

[support.srcloc] представляет source_location::current:

Любой звонок current который появляется как аргумент по умолчанию ([dcl.fct.default]) или как его подвыражение, должен соответствовать местоположению вызова функции, которая использует аргумент по умолчанию ([expr.call]).

Обратите внимание, что "аргумент по умолчанию ( [dcl.fct.default])" включает аргумент шаблона по умолчанию, но в приведенной выше цитате упоминается только "место вызова функции". Будет ли законно оценивать source_location::current() в контексте аргумента шаблона по умолчанию?

Рассмотрим этот код ( Live Demo):

#include <iostream>

//#include <source_location>
#include <experimental/source_location>

//using source_location = std::source_location;
using source_location = std::experimental::source_location;


struct literal {
  char data[64] = {'\0'}; // For simplicity, assume it is large enough to hold all possible values.
  constexpr literal(const char* src) {
    char* dst = &data[0];
    while(*src) *(dst++) = *(src++);
    *dst = '\0';
  }
};

struct location { // A structural type is needed since source_location is not a structural type.
  literal file;
  literal func;
  unsigned line;
  unsigned column;
  constexpr location(const char* file, const char* func, unsigned line, unsigned column)
    : file(file), func(func), line(line), column(column) {}
  constexpr location(const source_location& loc)
    : location(loc.file_name(), loc.function_name(), loc.line(), loc.column()) {}
};

template<location loc = source_location::current()> // line 30
void print() {
  std::cout << loc.file.data << ' ' << loc.func.data << ' ' << loc.line << ' ' << loc.column << std::endl;
}

void caller_1() {
  print(); // line 36
}

void caller_2() {
  print(); // line 40
}

int main() {
  caller_1();
  caller_2();
  return 0;
}

clang не компилируется с ошибкой:

ошибка: извините, не типовой аргумент шаблона типа "местоположение" еще не поддерживается

gcc заставляет его компилироваться, но дает странный результат: function_name() и line() указать разные места:

./example.cpp caller_1 30 0

./example.cpp caller_2 30 0

0 ответов

Другие вопросы по тегам