现代C++:常量、变量与类型推导
# 现代C++:常量、变量与类型推导
# constexpr
关键字
C++11 提供了 constexpr
显式的声明函数或对象构造函数在编译期会成为常量表达式。从 C++14 开始,constexpr
函数可以在内部使用局部变量、循环和分支等简单语句:
constexpr int fibonacci(const int n) {
if(n == 1) return 1;
if(n == 2) return 1;
return fibonacci(n-1) + fibonacci(n-2);
}
# C++17: if/switch
可以声明临时变量
std::vector<int> v{1, 3, 5, 7};
if (auto it = std::find(v.begin(), v.end(), 3);
it != v.end())
{
std::cout << "Found it!\n";
}
# auto
与 decltype
类型推导
两个关键字均实现了类型推导,decltype
关键字是为了解决 auto
只能对变量进行类型推导的缺陷而出现的。decltype
还可以对表达式进行类型推导。
# 尾返回类型推导
template<typename T, typename Y>
auto test01(T x, Y y) -> decltype(x+y)
{
return x + y;
}
auto res = test01<double, int>(3.14, 1);
# 万能推导( decltype(auto)
)
如果有一个表达式,我不知道他是个可变引用( int &
),常引用( int const &
),右值引用( int &&
)还是一个普通的值( int
),这时候可以用:
decltype(auto) p = func();
一个例子:实现将两个不同类型vector逐元素相加的函数
template<typename T1, typename T2>
auto add(std::vector<T1> const &a, std::vector<T2> const &b)
{
using T = decltype(T1{}+T2{});
std::vector<T> ret;
for (auto i = size_t(0); i < std::min(a.size(), b.size()); ++i )
{
ret.push_back(a[i]+b[i]);
}
return ret;
}
int main() {
auto a = std::vector{1,2,3,4,5};
auto b = std::vector{1.2,3.4,5.6};
auto c = add(a, b);
for (auto i = size_t(0); i < c.size(); ++i )
{
std::cout << c[i] << '\n';
}
return EXIT_SUCCESS;
}
# using: 创建类型别名
除了 typedef
外,可以用 using
创建类型别名:
typedef std::vector<int> VecInt;
using VecInt = std::vector<int>;
typedef int (*PFunc)(int);
using PFunc = int(*)(int);
# 结构化绑定
使用 std::tuple
可以囊括多个返回值,其中用 make_tuple
创建,在 C++17 之后完善了如何从元组中取元素
auto tup = std::make_tuple(3, 3.14f, "hello");
auto [name, age, height] = tup;
auto &[name, age, height] = tup;
auto &&[name, age, height] = tup;
结构化绑定不仅可以应用于 std::tuple
,还可以应用于任意用户自定义类。
struct MyClass
{
int x;
float y;
};
MyClass mc = {42, 3.14f};
auto [x, y] = mc;
std::cout << x << ", " << y << '\n';
编辑 (opens new window)
上次更新: 2023/08/16, 16:01:49