C++ 称为对象类型';自动';不是函数或函数指针
当我试图编译这个使用lambda类型变量模板的C++14代码时,我看到了来自Clang(3.4和3.5)的一个奇怪错误 ,删除了一些库C++ 称为对象类型';自动';不是函数或函数指针,c++,lambda,c++14,template-meta-programming,C++,Lambda,C++14,Template Meta Programming,当我试图编译这个使用lambda类型变量模板的C++14代码时,我看到了来自Clang(3.4和3.5)的一个奇怪错误 ,删除了一些库\u t和\u v内容,以使编译器满意: #include <type_traits> template <class T> class forward_if_wrapper { template <class U, class Enable = typename std::enable_if<std::is_lv
\u t
和\u 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));
}
再次:
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')
模板tx{0};//好的
模板自动x=T{0};//坏的
int main()
{
返回x+x;
}
错误。cc:6:19:错误:二进制表达式('auto'和'auto'的操作数无效)
根据@dyp和@ildjarn的评论:是的,这是Clang3.4(可能还有3.5)中的一个bug。它在Clang3.7.0(也许更早)中被修复。上提供了各种版本的Clang
及
#包括
模板
结构前向包装器{
模板
静态U向前(U&&U){
返回u;
}
模板
静态数据类型(自动)转发(U&&U){
返回静态_-cast(u);
}
};
模板自动转发=
[](auto&&u)->decltype(auto){return forward_wrapper::forward(u);};
// --------
#包括
#包括
空条(int&){put(“调用的复制函数”);}
空条(int&){put(“调用的移动函数”);}
模板
void foo(容器和c){
用于(自动和英语教学:c){
巴(前锋);;
}
}
int main(){
向量v={1,2};
傅(五),;
foo(std::move(v));
}
您问题中的代码片段可以用最新版本的clang++编译(将class
更改为struct
以便于访问)。这表明您看到的错误是一个已修复的编译器错误。@dyp万岁!你能告诉我clang--version
的输出吗?理想情况下,我希望找到一个像ideone或godbolt这样的在线服务,支持该版本的Clang。(甚至不支持变量模板。)通常有g++和clang++的最新版本,但我不确定是否可以将编译器开关调整为合理的(例如,-std=c++1y
)--编辑:啊,可以在页面左下角进行调整。也有g++和clang++的合理最新版本。我使用了clang版本3.7.0(trunk 228504),它应该是trunk atm的尖端。coliru上的clang++是clang版本3.5.0(tags/RELEASE\u 350/final 217394)
,并且说代码(带有struct
vsclass
fix)在那里工作得很好。
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')
#include <type_traits>
template <class T>
struct forward_wrapper {
template <class U, class Enable = std::enable_if_t<(sizeof(std::remove_reference<U>), std::is_reference<T>::value)>>
static U forward(U&& u) {
return u;
}
template <class U, class Enable = std::enable_if_t<(sizeof(std::remove_reference<U>), !std::is_reference<T>::value)>>
static decltype(auto) forward(U&& u) {
return static_cast<typename std::remove_reference<U>::type &&>(u);
}
};
template <class T> auto forward =
[](auto&& u) -> decltype(auto) { return forward_wrapper<T>::forward(u); };
// --------
#include <stdio.h>
#include <vector>
void bar(int &) { puts("Called copy function"); }
void bar(int &&) { puts("Called move function"); }
template<class Container>
void foo(Container&& c) {
for (auto&& elt : c) {
bar(forward<Container>(elt));
}
}
int main() {
std::vector<int> v = {1,2};
foo(v);
foo(std::move(v));
}