我有一个函数看起来差不多是这样的:
template<class C> auto f(C const& c) -> decltype(begin(c)){
using std::begin;
return begin(c);
}
该函数的主体利用了“
using
和use”习惯用法,并且由于使用了
decltype
,如果返回类型无效,则会进行SFINAE。
然而,通常情况下并不完美,因为我无法告诉decltype
在begin
上使用using std
声明。
template<class C> auto f(C const& c) -> decltype(std::begin(c))
这也可能是不一致的,例如当decltype(c)
和begin
属于不同的命名空间时。
有什么解决方法吗?
理想情况下,我希望有像这样的东西:
template<class C> auto f(C const& c) -> decltype(using std::begin; begin(c))
我认为原则上lambda函数可以发挥作用。
template<class C> auto f(C const& c) -> decltype([&]{using std::begin; return begin(c)})
但是在decltype
内部禁止使用lambda表达式。
在GCC中,有一种有趣的语言扩展(“表达式语句”),它很有前途,但它不能在函数体外部工作(与lambda表达式不允许在未求值上下文中相同)。否则,它将是一种解决方案。
template<class C> auto g(C const& c)
->decltype(({using std::begin; begin(c);})){ // ...that doesn't work here
return(({using std::begin; begin(c);})); // gcc extesion...
}
detail::f
。 - n. m.maybe_std_begin
放在detail
或类似的私有命名空间中。所以你只是省略了尾随返回类型。这导致你的版本具有auto
的返回类型推断,而我的版本具有decltype
的行为,虽然对于像begin
这样的东西应该没有关系,但如果f
调用了其他函数,则可能存在影响。 - Praetorian