Getting started with C++TemplatesMetaprogrammingIteratorsReturning several values from a functionstd::stringNamespacesFile I/OClasses/StructuresSmart PointersFunction Overloadingstd::vectorOperator OverloadingLambdasLoopsstd::mapThreadingValue CategoriesPreprocessorSFINAE (Substitution Failure Is Not An Error)The Rule of Three, Five, And ZeroRAII: Resource Acquisition Is InitializationExceptionsImplementation-defined behaviorSpecial Member FunctionsRandom number generationReferencesSortingRegular expressionsPolymorphismPerfect ForwardingVirtual Member FunctionsUndefined BehaviorValue and Reference SemanticsOverload resolutionMove SemanticsPointers to membersPimpl Idiomstd::function: To wrap any element that is callableconst keywordautostd::optionalCopy ElisionBit OperatorsFold ExpressionsUnionsUnnamed typesmutable keywordBit fieldsstd::arraySingleton Design PatternThe ISO C++ StandardUser-Defined LiteralsEnumerationType ErasureMemory managementBit ManipulationArraysPointersExplicit type conversionsRTTI: Run-Time Type InformationStandard Library AlgorithmsFriend keywordExpression templatesScopesAtomic Typesstatic_assertoperator precedenceconstexprDate and time using <chrono> headerTrailing return typeFunction Template OverloadingCommon compile/linker errors (GCC)Design pattern implementation in C++Optimization in C++Compiling and BuildingType Traitsstd::pairKeywordsOne Definition Rule (ODR)Unspecified behaviorFloating Point ArithmeticArgument Dependent Name Lookupstd::variantAttributesInternationalization in C++ProfilingReturn Type CovarianceNon-Static Member FunctionsRecursion in C++Callable Objectsstd::iomanipConstant class member functionsSide by Side Comparisons of classic C++ examples solved via C++ vs C++11 vs C++14 vs C++17The This PointerInline functionsCopying vs AssignmentClient server examplesHeader FilesConst Correctnessstd::atomicsData Structures in C++Refactoring TechniquesC++ StreamsParameter packsLiteralsFlow ControlType KeywordsBasic Type KeywordsVariable Declaration KeywordsIterationtype deductionstd::anyC++11 Memory ModelBuild SystemsConcurrency With OpenMPType Inferencestd::integer_sequenceResource Managementstd::set and std::multisetStorage class specifiersAlignmentInline variablesLinkage specificationsCuriously Recurring Template Pattern (CRTP)Using declarationTypedef and type aliasesLayout of object typesC incompatibilitiesstd::forward_listOptimizationSemaphoreThread synchronization structuresC++ Debugging and Debug-prevention Tools & TechniquesFutures and PromisesMore undefined behaviors in C++MutexesUnit Testing in C++Recursive MutexdecltypeUsing std::unordered_mapDigit separatorsC++ function "call by value" vs. "call by reference"Basic input/output in c++Stream manipulatorsC++ ContainersArithmitic Metaprogramming

Variable Declaration Keywords

Other topics

const

A type specifier; when applied to a type, produces the const-qualified version of the type. See const keyword for details on the meaning of const.

const int x = 123;
x = 456;    // error
int& r = x; // error

struct S {
    void f();
    void g() const;
};
const S s;
s.f(); // error
s.g(); // OK

decltype

C++11

Yields the type of its operand, which is not evaluated.

  • If the operand e is a name without any additional parentheses, then decltype(e) is the declared type of e.

    int x = 42;
    std::vector<decltype(x)> v(100, x); // v is a vector<int>
    
  • If the operand e is a class member access without any additional parentheses, then decltype(e) is the declared type of the member accessed.

    struct S {
        int x = 42;
    };
    const S s;
    decltype(s.x) y; // y has type int, even though s.x is const
    
  • In all other cases, decltype(e) yields both the type and the value category of the expression e, as follows:

    • If e is an lvalue of type T, then decltype(e) is T&.
    • If e is an xvalue of type T, then decltype(e) is T&&.
    • If e is a prvalue of type T, then decltype(e) is T.

    This includes the case with extraneous parentheses.

    int f() { return 42; }
    int& g() { static int x = 42; return x; }
    int x = 42;
    decltype(f()) a = f(); // a has type int
    decltype(g()) b = g(); // b has type int&
    decltype((x)) c = x;   // c has type int&, since x is an lvalue
    
C++14

The special form decltype(auto) deduces the type of a variable from its initializer or the return type of a function from the return statements in its definition, using the type deduction rules of decltype rather than those of auto.

const int x = 123;
auto y = x;           // y has type int
decltype(auto) z = x; // z has type const int, the declared type of x

signed

A keyword that is part of certain integer type names.

  • When used alone, int is implied, so that signed, signed int, and int are the same type.
  • When combined with char, yields the type signed char, which is a different type from char, even if char is also signed. signed char has a range that includes at least -127 to +127, inclusive.
  • When combined with short, long, or long long, it is redundant, since those types are already signed.
  • signed cannot be combined with bool, wchar_t, char16_t, or char32_t.

Example:

signed char celsius_temperature;
std::cin >> celsius_temperature;
if (celsius_temperature < -35) {
    std::cout << "cold day, eh?\n";
}

unsigned

A type specifier that requests the unsigned version of an integer type.

  • When used alone, int is implied, so unsigned is the same type as unsigned int.
  • The type unsigned char is different from the type char, even if char is unsigned. It can hold integers up to at least 255.
  • unsigned can also be combined with short, long, or long long. It cannot be combined with bool, wchar_t, char16_t, or char32_t.

Example:

char invert_case_table[256] = { ..., 'a', 'b', 'c', ..., 'A', 'B', 'C', ... };
char invert_case(char c) {
    unsigned char index = c;
    return invert_case_table[index];
    // note: returning invert_case_table[c] directly does the
    // wrong thing on implementations where char is a signed type
}

volatile

A type qualifier; when applied to a type, produces the volatile-qualified version of the type. Volatile qualification plays the same role as const qualification in the type system, but volatile does not prevent objects from being modified; instead, it forces the compiler to treat all accesses to such objects as side effects.

In the example below, if memory_mapped_port were not volatile, the compiler could optimize the function so that it performs only the final write, which would be incorrect if sizeof(int) is greater than 1. The volatile qualification forces it to treat all sizeof(int) writes as different side effects and hence perform all of them (in order).

extern volatile char memory_mapped_port;
void write_to_device(int x) {
    const char* p = reinterpret_cast<const char*>(&x);
    for (int i = 0; i < sizeof(int); i++) {
        memory_mapped_port = p[i];
    }
}

Contributors

Topic Id: 7840

Example Ids: 18509,18513,18685,18686,19102

This site is not affiliated with any of the contributors.