我想问一下是否有人知道为什么以下提供的示例代码在以下情况下无法编译:
1)MSVC 2013 with boost
2)GCC与-std = c ++ 11
相同的代码编译精细
1)在MSVC中,当boost :: result_of与std等效的一个交换时
2)在GCC中,当-std = c ++ 11标志未启用时,它编译正常。如果使用std :: result_of启用它没有帮助。
我很疑惑为什么会出现这样的错误,所以我想说清楚。
下面的类是尽可能少的,我可以让它重现我自己,所以它在使用中可能没有多大意义,但它显示了编译器错误。
#include <cstdint> // or #include <boost/cstdint.hpp>
#include <vector>
//#include <type_traits> // for C11
#include <boost/type_traits.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/static_assert.hpp> // if C11 is not enabled for static assert
template <class SrcT, class DstT>
struct CopyCVR
{
typedef typename boost::remove_reference<SrcT>::type base_src;
typedef typename boost::remove_cv<typename boost::remove_reference<DstT>::type>::type base_dst;
typedef typename boost::mpl::if_< boost::is_volatile<base_src>, volatile base_dst, base_dst >::type v_dst;
typedef typename boost::mpl::if_< boost::is_const<base_src>, const v_dst, v_dst >::type cv_dst;
typedef typename boost::mpl::if_< boost::is_reference<SrcT>, cv_dst&, cv_dst >::type type;
};
template <class typeT>
class Element2
{
typeT elem[2];
public:
typedef typeT elemType;
Element2() { elem[0] = elem[1] = 0; }
typeT& operator[](size_t i) { return elem[i]; }
};
template <class elementT>
class List
{
std::vector<elementT> m_List;
public:
typedef elementT list_type;
typedef elementT& result_type;
List() {};
result_type operator[](size_t i) { return m_List[i]; }
void Add(const elementT& el) { this->m_List.push_back(el); }
};
template <class ResultT, class typeT>
inline ResultT select(typeT& elem, int32_t num)
{
return elem[num];
}
template <class List>
struct SelectFunctor
{
int32_t m_elem;
public:
SelectFunctor(int32_t elem) : m_elem(elem) {}
typedef typename List::list_type::elemType listElem_type;
typedef typename CopyCVR<typename List::result_type, listElem_type>::type result_type;
result_type operator()(typename List::result_type elem) const
{
return select<result_type>(elem, m_elem);
}
};
以下是使用上述类的代码示例。
int main(int argc, _TCHAR* argv[])
{
typedef List<Element2<double>> ListDouble;
ListDouble list;
SelectFunctor<ListDouble> sel(1);
list.Add(Element2<double>());
double val = sel(list[0]);
#if 1 // this return a compiler error
typedef boost::result_of< SelectFunctor<ListDouble>(typename ListDouble::list_type)>::type result_type;
#else // this is OK
typedef std::result_of< SelectFunctor<ListDouble>(typename ListDouble::list_type)>::type result_type;
#endif
static_assert(std::is_same<result_type, double&>::value, "Error");
}
在MSVC + boost的情况下,编译器错误是 错误C2039:'type':不是'boost :: result_of(Element2)&gt;'的成员
在GCC中,我可以使用boost进行编译,检查示例代码和编译结果
http://coliru.stacked-crooked.com/a/a80c29d736437eab
但是,如果在-std = c ++ 11中启用C11并且没有代码更改则失败。在这种情况下提到甚至交换boost :: result_of与std等效的一个没有帮助。类似的编译错误记录在
http://coliru.stacked-crooked.com/a/629ee3cdb9376376
有什么想法吗?
答案 0 :(得分:4)
typedef boost::result_of<SelectFunctor<ListDouble>(typename ListDouble::list_type &) >::type result_type;
// ^
SelectFunctor
的函数调用运算符需要typename List::result_type
,这是elementT&
的别名。您的result_of
询问是否可以使用typename ListDouble::list_type
(typename
是不必要的,BTW)来调用它,elementT
。
无法使用右值elementT
调用仿函数,因为您无法将非常量左值引用绑定到右值。因此,result_of
中没有type
嵌套的typedef。