我遇到函数boost::make_iterator_range
(我希望隐藏一个别名后面的提升,以防这个特定的库在将来的某个时候被采用到标准中。)
有什么方法可以使它起作用吗?
#include <boost/range/iterator_range.hpp>
void Foo()
{
}
template< typename T >
void Bar()
{ }
template< typename T >
void Bar(char c)
{ }
void (&FooAlias)() = Foo; // ok
void (&BarAlias)() = Bar<int>; // ok
// boost::iterator_range<const size_t*> (&MakeIterRangeAlias)(const size_t*,const size_t*) =
// boost::make_iterator_range<const size_t*>; // not ok
int main(int argc, char** argv)
{
const size_t v[] = { 3, 5, 1, 5, 29, 15 };
boost::iterator_range<const size_t*> r
= boost::make_iterator_range( std::begin( v ), std::end( v )); // want to alias this
return 0;
}
错误消息是:
In file included from /usr/include/boost/iterator/iterator_categories.hpp:15:0,
from /usr/include/boost/iterator/detail/facade_iterator_category.hpp:7,
from /usr/include/boost/iterator/iterator_facade.hpp:14,
from /usr/include/boost/range/iterator_range_core.hpp:23,
from /usr/include/boost/range/iterator_range.hpp:13,
from sandbox.cpp:2:
/usr/include/boost/mpl/eval_if.hpp: In instantiation of ‘boost::mpl::eval_if_c<true, boost::range_const_iterator<const long unsigned int*>, boost::range_mutable_iterator<const long unsigned int* const> >’:
/usr/include/boost/range/iterator.hpp:63:63: instantiated from ‘boost::range_iterator<const long unsigned int* const>’
sandbox.cpp:20:10: instantiated from here
/usr/include/boost/mpl/eval_if.hpp:60:31: error: no type named ‘type’ in ‘boost::mpl::eval_if_c<true, boost::range_const_iterator<const long unsigned int*>, boost::range_mutable_iterator<const long unsigned int* const> >::f_ {aka struct boost::range_const_iterator<const long unsigned int*>}’
/usr/include/boost/mpl/eval_if.hpp: In instantiation of ‘boost::mpl::eval_if_c<false, boost::range_const_iterator<const long unsigned int*>, boost::range_mutable_iterator<const long unsigned int*> >’:
/usr/include/boost/range/iterator.hpp:63:63: instantiated from ‘boost::range_iterator<const long unsigned int*>’
sandbox.cpp:20:10: instantiated from here
/usr/include/boost/mpl/eval_if.hpp:60:31: error: no type named ‘type’ in ‘boost::mpl::eval_if_c<false, boost::range_const_iterator<const long unsigned int*>, boost::range_mutable_iterator<const long unsigned int*> >::f_ {aka struct boost::range_mutable_iterator<const long unsigned int*>}’
sandbox.cpp:20:10: error: invalid initialization of non-const reference of type ‘void (&)(const size_t*, const size_t*) {aka void (&)(const long unsigned int*, const long unsigned int*)}’ from an rvalue of type ‘<unresolved overloaded function type>’
make: *** [sandbox] Error 1
答案 0 :(得分:5)
使用函数指针是一种对函数进行别名的次优方法。它不像原版那样灵活(它不再是模板),你现在需要知道函数的确切签名,这可能是稳定的,也可能是不稳定的。 而是尝试这种方法。
template< typename ... Args >
auto MakeIterRangeAlias( Args&& ... args ) -> decltype( /* copy return line here */ )
{
return boost::make_iterator_range( std::forward<Args>(args)... );
}
由于您的工作几乎没有,别名支持原始的确切签名。即使它发生了巨大的变化,你仍然会被设定。此外,与函数指针方法不同,优化器将能够简单地内联MakeIterRangeAlias,以便不存在运行时开销。