c ++ 11使用函数中定义的类中的函数模板参数

时间:2014-03-28 13:45:49

标签: templates c++11 g++ clang most-vexing-parse

我对以下代码有两个问题:

为什么版本/ * 1 * /在g ++下编译并且版本/ * 2 * /不?

为什么这段代码不能在clang中编译?

我知道如何修复它。但我想明白为什么它不起作用。

#include <boost/test/unit_test.hpp>

template<typename T,typename Cmp>
class queue{
public:
    queue(Cmp c):cmp(c){};
    void push(T a){
        cmp(a,a);
    }
    Cmp cmp;

};

template<typename T>
void fun(T a){
    class decreasing_order
    {
    public:
        decreasing_order(std::vector<T>  BBB):AAA(BBB) {}
        std::vector<T>  AAA;
        bool operator() (const T & lhs, const T & rhs) const
        {
            return AAA[lhs]<AAA[rhs];
        }
    };
    std::vector<T> tab;
    queue<T,  decreasing_order >uncoveredSetQueue((decreasing_order(tab)));/*1*/
 // queue<T,  decreasing_order >uncoveredSetQueue( decreasing_order(tab) );/*2*/
    uncoveredSetQueue.push(a);

}

BOOST_AUTO_TEST_CASE(TestX) {
    fun(1);
}

在clang中我收到以下错误:

test.cpp:25:20: error: 
      'fun(int)::decreasing_order::operator()(const int &, const int
      &)::decreasing_order::AAA' is not a member of class 'const
      decreasing_order'
            return AAA[lhs]<AAA[rhs];
                   ^
/home/piotr/git/paal/test/greedy/test.cpp:10:9: note: in instantiation of
      member function 'fun(int)::decreasing_order::operator()' requested
      here
        cmp(a,a);
        ^
/home/piotr/git/paal/test/greedy/test.cpp:30:23: note: in instantiation
      of member function 'queue<int, decreasing_order>::push' requested
      here
    uncoveredSetQueue.push(a);
                  ^
/home/piotr/git/paal/test/greedy/test.cpp:35:5: note: in instantiation of
      function template specialization 'fun<int>' requested here
    fun(1);
    ^
1 error generated.

我使用g ++ 4.8.1和clang 3.4-1。

1 个答案:

答案 0 :(得分:1)

queue<T,  decreasing_order >uncoveredSetQueue( decreasing_order(tab) );/*2*/

Most Vexing Parse的示例:它声明了一个名为uncoveredSetQueue的函数,它接受类型为tab的参数(此处为decreasing_order}并返回queue<T, decreasing_order> }。正如您所发现的那样,添加括号可以避免最令人烦恼的解析。您也可以用{}替换括号以使用统一初始化语法。

clang错误消息对我来说看起来像编译器错误。很可能它并没有正确处理使用本地类型作为模板参数的一些后果(这在C ++ 03中是不允许的,并且是新的C ++ 11特性)。