C++
Declarations
auto
For variables, specifies that the type of the variable that is being declared will be automatically deduced from its initializer.
- For functions, specifies that the return type will be deduced from its return statements. (since C++14)
- For non-type template parameters, specifies that the type will be deduced from the argument. (since C++17)
Language linkage
Provides for linkage between modules written in different programming languages.
extern string-literal { declaration-seq(optional) } (1)
extern string-literal declaration (2)
(1) Applies the language specification string-literal
to all function types, function names with external linkage and variables with external linkage declared in declaration-seq
.
(2) Applies the language specification string-literal
to a single declaration
or definition
.
- string-literal - The name of the required language linkage
- declaration-seq - a sequence of declarations, which may include nested linkage specifications
- declaration - a declaration
Since language linkage is part of every function type, pointers to functions maintain language linkage as well. Language linkage of function types (which represents calling convention) and language linkage of function names (which represents name mangling) are independent of each other:
extern "C" void f1(void(*pf)()); // declares a function f1 with C linkage, which returns void and takes a
// pointer to a C function which returns void and takes no parameters
extern "C" typedef void FUNC(); // declares FUNC as a C function type that returns void and takes no parameters
FUNC f2; // the name f2 has C++ linkage, but its type is C function
extern "C" FUNC f3; // the name f3 has C linkage and its type is C function void()
void (*pf2)(FUNC*); // the name pf2 has C++ linkage, and its type is
// "pointer to a C++ function which returns void and takes one
// argument of type 'pointer to the C function which returns void
// and takes no parameters'"
extern "C" {
static void f4(); // the name of the function f4 has internal linkage (no language, because of static)
// but the function's type has C language linkage
}
Special rules for “C” linkage
- When class member declarations and member function type declarations appear in a “C” language block, their linkage remains “C++”.
- When two functions with the same unqualified name are declared in different namespaces, and both have “C” language linkage, the declarations refer to the same function.
- When two variables with “C” language linkage and the same name that appear in different namespaces, they refer to the same variable.
- A “C” variable and a “C” function cannot have the same name, regardless if they are defined in the same or different namespaces.
Note:
- Language specifications can only appear in namespace scope. The braces of the language specification do not establish a scope.
extern "C"
makes it possible to include header files containing declarations of C library functions in a C++ program, but if the same header file is shared with a C program, extern “C” (which is not allowed in C) must be hidden with an appropriate#ifdef
, typically__cplusplus
.
namespace
std::string str0; // 表示 std 命名空间下的 string 类
// 直接 `::` 开始,表示顶层命名空间(全局变量),如:
::std::string str1;
tensorflow::Status Readable(const string& filename,
const file::Options& options) {
return ToStatus(::file::Readable(filename, ::file::Defaults()));
}
template
template 示例代码
// tensorflow-r1.12/tensorflow/contrib/lite/toco/model.h
enum class ArrayDataType : uint8 {
kNone, // 0
kBool,
kFloat,
kInt8,
kUint8,
kInt16, // 5
kUint16,
kInt32,
kUint32,
kInt64,
kUint64, // 10
kString,
kComplex64,
};
// Compile-time logic to map ArrayDataType to the corresponding C++ scalar type
template <ArrayDataType A>
struct DataTypeImpl {};
template <>
struct DataTypeImpl<ArrayDataType::kNone> {
typedef int Type;
};
template <>
struct DataTypeImpl<ArrayDataType::kBool> {
typedef bool Type;
};
template <ArrayDataType A>
using DataType = typename DataTypeImpl<A>::Type;
utility library
std::initializer_list
An object of type std::initializer_list<T>
is a lightweight proxy object that provides access to an array of objects of type const T.
A std::initializer_list
object is automatically constructed when:
- a braced-init-list is used to list-initialize an object, where the corresponding constructor accepts an
std::initializer_list
parameter - a braced-init-list is used as the right operand of assignment or as a function call argument, and the corresponding assignment operator/function accepts an
std::initializer_list
parameter - a braced-init-list is bound to auto, including in a ranged for loop
Initializer lists may be implemented as a pair of pointers or pointer and length. Copying a std::initializer_list
does not copy the underlying objects.
misc
int
In C and C++, 1LL/1ll
and 2LL/2ll
simply means the numbers 1
or 2
saved using at least 64 bits. It’s called a long long integer.
In other words, it’s 1
or 2
stored as follow binary (if 64 bits are used).
0000000000000000000000000000000000000000000000000000000000000001 // 1
0000000000000000000000000000000000000000000000000000000000000010 // 2