Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 称为对象类型';自动';不是函数或函数指针_C++_Lambda_C++14_Template Meta Programming - Fatal编程技术网

C++ 称为对象类型';自动';不是函数或函数指针

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

当我试图编译这个使用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_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
vs
class
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));
}