Рассмотрим следующий код:
template <int N, typename T> void f(T) { }
template <typename T>
constexpr int k(T&) { return 0; }
int main()
{
constexpr auto i = 1;
f<k(i)>([&i]
{
f<k(i)>(0);
});
}
clang++
(транк) компилирует его.g++
(транк) завершается с ошибкой:
<source>: In lambda function:
<source>:11:19: error: no matching function for call to 'f<k<const int>((* & i))>(int)'
11 | f<k(i)>(0);
| ^
<source>:1:35: note: candidate: 'template<int N, class T> void f(T)'
1 | template <int N, typename T> void f(T) { }
| ^
<source>:1:35: note: template argument deduction/substitution failed:
<source>:11:19: error: '__closure' is not a constant expression
11 | f<k(i)>(0);
| ^
<source>:11:13: note: in template argument for type 'int'
11 | f<k(i)>(0);
| ~^~~
живой пример на godbolt.org
Изменение k(T&)
на k(T)
решает проблему.Мне кажется, что проблема связана с тем, что ссылочный аргумент не является константным выражением , но он не используется как часть k
.
Какой компиляторздесь правильно?