Showing posts with label cpp11_char. Show all posts
Showing posts with label cpp11_char. Show all posts

Nov 9, 2025

[C++] Use string_view _sv over raw char string

Reference:
https://youtu.be/jXQ6WtYmfZw?si=B_C-UXBVCFpAODVh&t=4428


std:: string s("the foo and the bar");
std:: println("{}", std::ranges::contains_subrange(s, "foo" ));
This won't work due to C-style string literal "foo" is actually a range of four characters: 
['f', 'o', 'o', '\0'] 

Easy fix:
#include <iostream>
#include <string>
#include <string_view>
#include <ranges>
#include <print> // C++23 for std::println

int main() {
    using namespace std::literals; // Enables the "sv" suffix

    std::string s("the foo and the bar");
    
    // "foo"sv creates a std::string_view of length 3.
    // This will now print "true".
    std::println("{}", std::ranges::contains_subrange(s, "foo"sv)); 
}

or C++23:
std::string s("the foo and the bar");

// This is the simplest way and does what you expect.
// It will print "true".
std::println("{}", s.contains("foo"));

Aug 20, 2015

[C++11/14] constant expression value can convert to smaller size data structure

#include <initializer_list>
#include <iostream>

using namespace std;

struct Test{
    Test(initializer_list<char> list){
        cout << "IL constructor" << endl;
    }

    Test(int a, char c){
        cout << "general constructor" << endl;
    }
};


template<char c, int i>
void fun(){
    /*
        8.5.4/7:
        A narrowing conversion is an implicit conversion […] from an integer
        type or unscoped enumeration type to an integer type that cannot
        represent all the values of the original type, except where the source
        is a constant expression and the actual value after conversion will
        fit into the target type and will produce the original value when
        converted back to the original type.
    */
    Test{i, c};  // print: IL constructor
}

int main(){
    fun<'^', 3>();
    Test('^', 4);  // print: general constructor
}

Jan 31, 2015

[C++] char16_t / char32_t

http://en.cppreference.com/w/cpp/language/types

char16_t and char32_t are guaranteed unsigned.

N4296 3.9.1 [basic.fundamental]/5: "Types char16_t and char32_t denote distinct types with the same size, signedness, and alignment as uint_least16_t and uint_least32_t, respectively, in <cstdint>, called the underlying types.

Oct 23, 2014

[C][C++] difference between char array[] and char *array, why char [] not char* could be used in non-type argument for template.

Reference:

quote:
A string literal is a literal with array type, and in C there is no way for an array type to exist in an expression except as an lvalue. 
String literals could have been specified to have pointer type (rather than array type that usually decays to a pointer) pointing to the string "contents", but this would make them rather less useful; in particular, the sizeof operator could not be applied to them. 

Note that C99 introduced compound literals, which are also lvalues, so having a literal be an lvalue is no longer a special exception; it's closer to being the norm.

quote:

const char hello[] = {'h', 'e', 'l', 'l', 'o', '\0'};

This creates an array of 6 bytes in writable memory (on the stack if this is inside a function, in a data segment if directly at global scope or inside a namespace), to be initialized with the ASCII codes for each of those characters in turn.
i.e 以上可以被take address, 可以用於C++ template non-type parameter.

char *hello = "hello";

此為runtime(其所在記憶體位置由loader決定), 不能被take address at compile time, 故不能用於template non-type parameter.

"hello" is a string literal,
which typically means: the OS loader code that loads your program into memory and starts it running will have copied the text "hello\0" from your executable image into some memory that will then have been set to be read only, and a separate variable named "hello" - which is of whatever size pointers are in your program (e.g. 4 bytes for 32-bit applications, 8 for 64-bit) - will exist on the stack (if the line above appears inside a function) or in writable memory segment (if the line is at global or namespace scope), and the address of the former textual data will be copied into the hello pointer. you can change hello to point somewhere else (e.g. to another language's equivalent text), but normally shouldn't try to change the string literal to which the above code points hello.

Beware not to modify char*, which should be const char*, since we could cache the char string with same value at the beginning.