# Variable templates
template<class T>
constexpr T pi = T(3.1415926535897932385);
# decltype(U)()
std::declval<const U&>()
std::decay_t<U>
# class decoration
#include <cassert>
namespace jc {
template <typename>
struct get_class;
template <typename ClassType, typename MemberType>
struct get_class<MemberType ClassType::*> {
using type = ClassType;
};
template <typename T>
using get_class_t = typename get_class<T>::type;
template <auto ClassMember>
class Wrapper {
public:
Wrapper(get_class_t<decltype(ClassMember)>& obj) : obj_(obj) {}
void increase() { ++(obj_.*ClassMember); }
private:
get_class_t<decltype(ClassMember)>& obj_;
};
struct A {
int i = 0;
};
} // namespace jc
int main() {
jc::A a;
jc::Wrapper<&jc::A::i>{a}.increase();
assert(a.i == 1);
}
# 打印源代码位置
#include <source_location>
const std::source_location &l =
std::source_location::current();
std::string location_to_str(const std::source_location &l)
{
return std::string(l.file_name()) + ":" + std::to_string(l.line()) +
":" + l.function_name() + "()";
}
# C++版本判断
c++11 = 199711L
c++17 = 201703L
c++20 = 202002L
cout << __cplusplus << endl;
#if __cpluscplus >= 199711L
#else
#endif
# 打印线程ID
std::this_thread::get_id()
# 代运算符号 and not or
#include <iso646.h>
int main(int argc, char* argv[]) {
int i = 1;
if (i < 2 and i > 0) // == if(i<2 && i>0)
std::cout << "test " << i << "\n";
return 0;
}
# 返回数组长度
template<typename T, std::size_t N>
constexpr std::size_t arraySize(T (&)[N]) noexcept
{
return N;
}
int keyVals[] = {1, 3, 5, 7, 9}; // length 5
int mappedVals[arraySize(keyVals)]; // the same as keyVals
# Visual Studio _MSC_VER 版本号
| Visual Studio 版本 | `_MSC_VER` |
| :----------------------------------- | :--------- |
| Visual Studio 6.0 | 1200 |
| Visual Studio .NET 2002 (7.0) | 1300 |
| Visual Studio .NET 2003 (7.1) | 1310 |
| Visual Studio 2005 (8.0) | 1400 |
| Visual Studio 2008 (9.0) | 1500 |
| Visual Studio 2010 (10.0) | 1600 |
| Visual Studio 2012 (11.0) | 1700 |
| Visual Studio 2013 (12.0) | 1800 |
| Visual Studio 2015 (14.0) | 1900 |
| Visual Studio 2017 RTW (15.0) | 1910 |
| Visual Studio 2017 版本 15.3 | 1911 |
| Visual Studio 2017 版本 15.5 | 1912 |
| Visual Studio 2017 版本 15.6 | 1913 |
| Visual Studio 2017 15.7 版 | 1914 |
| Visual Studio 2017 版本 15.8 | 1915 |
| Visual Studio 2017 版本 15.9 | 1916 |
| Visual Studio 2019 RTW (16.0) | 1920 |
| Visual Studio 2019 版本 16.1 | 1921 |
| Visual Studio 2019 版本 16.2 | 1922 |
| Visual Studio 2019 版本 16.3 | 1923 |
| Visual Studio 2019 版本 16.4 | 1924 |
| Visual Studio 2019 版本 16.5 | 1925 |
| Visual Studio 2019 版本 16.6 | 1926 |
| Visual Studio 2019 版本 16.7 | 1927 |
| Visual Studio 2019 v16.8、v16.9 | 1928 |
| Visual Studio 2019 版本 16.10、16.11 | 1929 |
| Visual Studio 2022 RTW (17.0) | 1930 |
__DATE__ = 当前源文件编译日期
# PIMPL设计,隐藏细节
//widget.h
class Widget { //跟之前一样,在“widget.h”中
public:
Widget();
~Widget(); //只有声明语句
…
private: //跟之前一样
struct Impl;
std::unique_ptr<Impl> pImpl;
};
//widget.cpp
#include "widget.h"
#include "gadget.h"
#include <string>
#include <vector>
struct Widget::Impl {
std::string name;
std::vector<double> data;
Gadget g1,g2,g3;
};
Widget::Widget() //根据条款21,通过std::make_unique
: pImpl(std::make_unique<Impl>()) //来创建std::unique_ptr
{}
08-29
03-04
36万+
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
05-04
414
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
03-04
1229
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
08-30
4625
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)