const char* str = ""; // unmodifiable, can't change -> undefined behavior
char str[] = ""; // mutable
// Incorrect usage
std::string str = "a" + "b"; // not allowed
// Correct usage
std::string str = "a"s + "b" + std::to_string("c") + std::string("d");
int a { 5 }; // not const at all
const int b { a }; // runtime const (initializer is non-const)
int const c { 5 }; // compile-time const (initializer is a constant expression)
#define gravity 9.8
Refer to the Literal Suffixes Table.
A constant expression is an expression where everything can be evaluated at compile time.
constexpr double gravity { 9.8 };
constexpr int myAge { age }; // compile error: age is not a constant expression
#define GFORCE_CONSTEXPR(expr) []() { constexpr auto x = (expr); return x; }()
int global = GFORCE_CONSTEXPR(constexpr_sqrt(42.0));
Term | Definition |
---|---|
Compile-time constant | A value or non-modifiable object whose value must be known at compile time. |
Constexpr | Keyword declaring variables as compile-time constants and functions for evaluation. |
Constant expression | An expression containing only compile-time constants and supporting operators. |
Runtime expression | An expression not classified as a constant expression. |
Runtime constant | A value or non-modifiable object not classified as a compile-time constant. |
inline int min(int x, int y) // inline function
{
return (x < y) ? x : y;
}
#include <type_traits> // for std::is_constant_evaluated()
constexpr int someFunction()
{
if (std::is_constant_evaluated()) // if evaluating in constant context
doSomething();
else
doSomethingElse();
}
consteval int greater(int x, int y) // function is now consteval
consteval auto compileTimeEval(auto value)
#include <string>
std::string s{"text"}; // class type
s.length();
std::string name{};
std::cin >> name; // breaks on whitespace
std::getline(std::cin >> std::ws, name); // ignores leading whitespace
void doSomething(const std::string&); // pass by reference
namespace std::literals::string_literals
using namespace std::string_view_literals;
#include <string_view>
#include <string>
std::cout << "foo\n"; // C-style string literal
std::cout << "goo\n"s; // std::string literal
std::cout << "moo\n"sv; // std::string_view literal
// std::string_view can use constexpr, std::string can't
constexpr std::string_view s{ "Hello, world!" }; // s is a string symbolic constant
#include <iostream>
#include <string>
#include <string_view>
std::string getName()
{
std::string s{"sdasd"};
return s;
}
int main()
{
std::string s { "Alex" };
std::string_view name { getName() }; // dangling
std::cout << name << '\n'; // undefined behavior due to out-of-scope
return 0;
}
std::string_view
with a std::string
literal (causes dangling).std::string_view
over std::string
for read-only strings, especially for function parameters.std::string_view
with C-style string literals or std::string_view
literals.std::string s { "Hello, world!" };
std::string_view sv { s }; // sv is viewing s
s = "Hello, universe!"; // modifies s, invalidates sv
std::cout << sv << '\n'; // undefined behavior
sv = s; // revalidate sv
std::string_view sv { "Hello" };
sv.remove_prefix(1); // removes 'H'
sv.remove_suffix(1); // removes 'o'
Refer to the Insights on Strings and String Views and When to Use Strings and String Views.