随着GCC 4.8.0的发布,我们有一个支持自动返回类型推导的编译器,这是C++ 14的一部分.有了-std=c++1y,我可以这样做:
auto foo() { //deduced to be int
return 5;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:我应该何时使用此功能?什么时候需要,何时使代码更清洁?
我能想到的第一个场景是可能的.每个可以用这种方式编写的函数都应该是.这个问题是它可能并不总是使代码更具可读性.
下一个场景是避免更复杂的返回类型.作为一个很轻的例子:
template<typename T, typename U>
auto add(T t, U u) { //almost deduced as decltype(t + u): decltype(auto) would
return t + u;
}
Run Code Online (Sandbox Code Playgroud)
我不相信这确实会成为一个问题,虽然我认为在某些情况下明确依赖于参数的返回类型可能更清楚.
接下来,为了防止冗余:
auto foo() {
std::vector<std::map<std::pair<int, double>, int>> ret;
//fill ret in with stuff
return ret;
}
Run Code Online (Sandbox Code Playgroud)
在C++ 11中,我们有时可以return {5, 6, 7};代替向量,但这并不总是有效,我们需要在函数头和函数体中指定类型.这纯粹是多余的,自动返回类型扣除使我们免于冗余.
最后,它可以用来代替非常简单的功能:
auto position() {
return pos_;
}
auto area() {
return …Run Code Online (Sandbox Code Playgroud) 我有一个小类,内部使用几个STL列表
template<class T>
class MC_base {
using OBJ_LIST = std::list<T>;
using OBJ_VAL = typename OBJ_LIST::value_type;
using OBJ_ITR = typename OBJ_LIST::iterator;
using OBJ_CITR = typename OBJ_LIST::const_iterator;
OBJ_LIST A,B,C;
...
};
Run Code Online (Sandbox Code Playgroud)
使用这些using语句,如果我在类定义中编写一个迭代器,它看起来很漂亮:
OBJ_ITR begin() { return A.begin(); };
OBJ_ITR end() { return A.end(); };
OBJ_CITR begin() const { return A.begin(); };
OBJ_CITR end() const { return A.end(); };
Run Code Online (Sandbox Code Playgroud)
在类定义中再次编写新函数很容易,因为我可以OBJ_XXXX在需要时简单地使用名称.此外,如果我决定std::vector稍后更改容器类型(比方说),我只需更改一行,只要我的新容器支持所有相同的操作,一切都应该是无缝的.
但是,当我想在类定义之外定义一个新的类函数时,这是有问题的
template<class T>
OBJ_ITR MC_base<T>::foo(OBJ_ITR x) { ... }
Run Code Online (Sandbox Code Playgroud)
我不确定如何"带出"using语句,以便它们与模板一起正确工作,而不是为每个过于冗长的函数定义它们.另外,我不想用using语句污染命名空间.
有没有正确的方法using与模板一起使用?