Я вижу странную ошибку от Clang (3.4 и 3.5), когда пытаюсь скомпилировать этот код C++ 14, который использует шаблон переменной лямбда-типа.Тип вызываемого объекта 'auto' не является указателем функции или функции
Here's the C++14 code as I'd like to write it.
Here's a second version, с некоторыми из библиотеки _t
и _v
вещей удалены, чтобы сделать компилятор счастливого:
#include <type_traits>
template <class T>
class forward_if_wrapper {
template <class U, class Enable = typename std::enable_if<std::is_lvalue_reference<U>::value>::type>
static U forward(U&& u) {
return u;
}
template <class U, class Enable = typename std::enable_if<!std::is_lvalue_reference<U>::value>::type>
static U&& forward(U&& t) {
return static_cast<U&&>(t);
}
};
auto forward = [](auto&& t) { return forward_if_wrapper<decltype(t)>::forward(t); };
template <class T> auto forward_if = [](auto&& u) { return forward_if_wrapper<T>::forward(u); };
// --------
#include <stdio.h>
#include <vector>
template<class Elt>
void bar(Elt&& e) {
printf("Called %s\n", __PRETTY_FUNCTION__);
}
template<class Container>
void foo(Container&& c) {
for (auto&& elt : c) {
bar(forward_if<Container>(elt));
}
}
int main() {
std::vector<int> v = {1,2};
foo(v);
foo(std::move(v));
}
ошибкой я вижу из второго кода с Clang является:
test.cc:34:13: error: called object type 'auto' is not a function or function pointer
bar(forward_if<Container>(elt));
^~~~~~~~~~~~~~~~~~~~~~~
test.cc:43:5: note: in instantiation of function template specialization 'foo<std::__1::vector<int, std::__1::allocator<int> > &>' requested here
foo(v);
^
У меня нет доступа к любому другому компилятору, который поддерживает C++ 14 generic lambdas, поэтому Clan g - это все, что я тестировал.
Это моя ошибка или ошибка Клана?
Я склоняюсь к идее, что это ошибка в правилах создания шаблонов Клана: Кланг, кажется, относится к auto
как первоклассный гражданин в мире типов, а не как индикатор для выполнения вычитания типа.
test.cc:34:14: error: invalid argument type 'auto' to unary expression
bar((+forward_if<Container>)(elt));
^~~~~~~~~~~~~~~~~~~~~~
снова:
template<class T> T x{0}; // good
template<class T> auto x = T{0}; // bad
int main()
{
return x<int> + x<long>;
}
bad.cc:6:19: error: invalid operands to binary expression ('auto' and 'auto')
фрагмент кода в вашем вопросе компилируется нормально (после изменения '' class' к struct' для доступности) с последней версией лязгом ++. Это говорит о том, что ошибка, которую вы видите, является ошибкой компилятора, которая была исправлена. – dyp
@ dyp Ура! Можете ли вы рассказать мне о выходе «clang -version»? и в идеале я бы хотел найти онлайн-сервис, например ideone или godbolt, который поддерживает эту версию Clang. (http://ideone.com/jRZ5SD даже не поддерживает переменные шаблоны.) – Quuxplusone
[melpon.org/wandbox](http://melpon.org/wandbox) обычно имеет самые последние версии как g ++, так и clang ++, но Я не уверен, что вы можете настроить переключатели компилятора на что-то разумное (например, '-std = C++ 1y') - изменить: ah, вы можете настроить его в левом нижнем углу страницы. [coliru.stacked-crooked.com] (http: // http: //coliru.stacked-crooked.com/) также имеет достаточно последние версии как g ++, так и clang ++. Я использовал clang версии 3.7.0 (ствол 228504), который должен быть наклонным сундуком. – dyp