类型推导(auto, decltype)

1.auto关键字

auto关键字可以实现自动类型推导,如auto x = 1; auto x = 0.0;被自动推导为int和double类型。在内置类型上似乎并没有什么特别。但在STL容器操作中可大大简化代码。

//------初始代码
std::map<double, double> resultMap;
//...
std::map<double, double>::iterator it = resultMap.begin();
for (; it != resultMap.end(); ++it)
{
    //...
}

std::unordered_multimap<int, int> resultMap;
//...
std::pair<std::unordered_multimap<int, int>::iterator, std::unordered_multimap<int, int>::iterator>
range = resultMap.equal_range(key);

//------新语法
std::map<double, double> resultMap;
//...
for (auto it = resultMap.begin(); it != resultMap.end(); ++it)
{
    //...
}

std::unordered_multimap<int, int> resultMap;
auto range = map.equal_range(key);

此外,在很多情况下无法知道变量被定义的类型时也可以采用auto关键字。

 class A
{
public:
    static int get(void)
    {
        return 0;
    }
};

class B
{
public:
    static const char* get(void)
    {
        return "0";
    }
};

template <class C>
void func(void)
{
    auto val = C::get();//val可根据模版类型传入A或B推导出不同类型
    //...
}

2.decltype关键字

auto关键字修饰的变量必须被初始化才能确定所代表类型,即必须定义变量。decltype可以在编译时推导出一个表达式的类型。
语法 decltype(exp)
exp表示一个表达式。类似于sizeof,用来推导表达式的大小。Decltype推导过程在编译期间完成,并不会计算表达式的值。
实际应用:

//------用法1  简化代码
template<class ContainerT>
class Foo
{
    typename ContainerT::iterator it_;//可能有问题的一个定义
public:
    void func(ContainerT& container)
    {
        it_ = container.begin();
    }
    //...
};

{
    typedef const std::vector<int> container_t;
    container_t arr;
    Foo<container_t> foo;
    foo.func(arr);//传入报错,应该使用const_iterator
}

//该问题在98/03下只能加一个特化版本
typename ContainerT::const_iterator it_;
void func(const ContainerT& container);

//显然上述定法造成了代码重复,使用decltype可简化
decltype(ContainerT().begin()) it_;
void func(ContainerT& container)
{
    it_ = container.begin();
}
//------用法2 变量表达式抽取类型
vector<int> v;
decltype(v)::value_type i = 0;

typedef decltype(nullptr) nullptr_t;//通过编译器关键字定义类型
typedef decltype(sizeof(0)) size_t;

3.auto和decltype结合使用

template<typename R, typename T, typename U>
R add(T t, U u)
{
    return t + u;
}

int a = 1; float b = 2.0;
auto c = add<decltype(a + b)>(a, b);//这里decltype<a + b>只是为获取返回值类型

//-------新语法表示1
template <typename T, typename U>
auto add(T t, U u) ->decltype(t + u)//返回类型后置语法
{
    return t + u;
}

//-------新语法表示2
//返回类型后置语法解决函数返回值类型依赖于参数而导致难以确定返回值的问题
int& foo(int& i);
float foo(float& f);
template<typename T>
auto func(T& val) -> decltype(foo(val))
{
    return foo(val);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值