universal reference

The parameter reference is frequently used CPlusPlus program, but it is just suitable for left-value just like the following scene.

#include <iostream>

using namespace std;

template <typename T>
void f( T &param )
{
    cout << param << endl;
}

int main() {
    int value = 1;
    f( value );
    f( 3 );
    return 0;
}

Compiled error:

/Users/weiyang/CLionProjects/AllReference/main.cpp:14:5: error: no matching function for call to 'f'
    f( 3 );
    ^
/Users/weiyang/CLionProjects/AllReference/main.cpp:6:6: note: candidate function [with T = int] not viable: expects an l-value for 1st argument
void f( T &param )
     ^
1 error generated.

If we want to make both statements f( 3 ) and f( value ) work successfully, the syntax universal reference is necessary for the function’s parameter.

void f( T &&param )
{
    cout << param << endl;
}

std::move

C++11 support copy construction and move construction for a new object. There are no copying, destruction, and memory migration operations in the process. So it’s very effective.
After that, all data and status information transferred from an object to another one.

Example 1.

#include <iostream>

using namespace std;

int main() {
    int a = 12;
    printf( "a address: %p\n", &a );
    int b = std::move( a );
    printf( "a address: %p\n", &a );
    cout << a << ", " << b << endl;
    return 0;
}
/*
a address: 0019FB98
a address: 0019FB98
12, 12
 * */

Example 2.

#include <iostream>
#include <string>
using namespace std;

int main() {
    string str = "hello world";
    printf( "str address: %p\n", &str );
    string str1 = std::move( str );
    printf( "str address: %p\n", &str );
    cout << str << ", " << str1 << endl;
    return 0;
}
/*
str address: 009EF768
str address: 009EF768
, hello world
 * */

std::forward

The function is used to keep the original data type for the function parameter.

template<class T>
void wrapper(T&& arg) 
{
    // arg is always lvalue
    foo(std::forward<T>(arg)); // Forward as lvalue or as rvalue, depending on T
}

judge data type

Use typeinfo or boost::typeindex to judge the variable’s data type information, boost::typeindex will not remove type syntax symbol such as const and volatile so it tells us more details.

Example 1.

#include <iostream>
#include <string>
#include <typeinfo>
#include <boost/type_index.hpp>

using namespace std;
using boost::typeindex::type_id_with_cvr;

template<class T>
void wrapper(T& arg)
{
    cout << typeid( arg ).name() << endl;
    cout << type_id_with_cvr<T>().pretty_name() << endl;
}

int main() {
    const int a = 12;
    wrapper( a );
    auto b = &a;
    return 0;
}
/*
i
int const
*/

Example 2.

#include <iostream>
#include <string>
#include <typeinfo>
#include <boost/type_index.hpp>

using namespace std;
using boost::typeindex::type_id_with_cvr;

int main() {
    const char str[] =  "hello world";
    auto var = str[0];
    cout << type_id_with_cvr<decltype(var)>().pretty_name() << endl;
    return 0;
}
/*
char
 * */

std::array

The container std::array helps us to manage a fixed-size array. It provides some useful methods which we can modify array conveniently. We also can return an array by it in functions.

#include <iostream>
#include <vector>
#include <array>
#include <ctime>
#include <random>

template <typename T, size_t N>
std::array<T, N> getMyArray( int length )
{
    std::array<int, N> result;
    for( int i = 0; i < length; ++i )
    {
        result[i] = std::rand();
    }
    return result;
}

int main() {
    std::array<double, 3> pt0{ 0.0, 0.5, 1.0 };
    double origin[3] = { 10, 1, 11 };
    std::array<double, 3> pt1 = std::to_array( origin );

    pt0.fill( 0 );
    std::copy( pt0.begin(), pt0.end(), std::ostream_iterator<double>( std::cout, " " ) );
    std::cout << "\n";

    pt0.swap( pt1 );
    std::copy( pt0.begin(), pt0.end(), std::ostream_iterator<double>( std::cout, " " ) );
    std::cout << "\n";

    std::copy( pt1.begin(), pt1.end(), std::ostream_iterator<double>( std::cout, " " ) );
    std::cout << "\n";

    std::srand( std::time(nullptr) );
    auto intArray = getMyArray<int, 6>( 6 );
    std::copy( intArray.begin(), intArray.end(), std::ostream_iterator<double>( std::cout, " " ) );
    std::cout << "\n";
    return 0;
}

/*
0 0 0
10 1 11
0 0 0
41 18467 6334 26500 19169 15724
 * */
Categories: CPlusPlus

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments

Content Summary
: Input your strings, the tool can get a brief summary of the content for you.

X
0
Would love your thoughts, please comment.x
()
x