Creating const objects of a user class from constant pointers

Is it possible to get the compiler to distribute const-qualifier in my class to provide const pointers to the constructor? Consider the following code:

struct T
{
    T(int * a, int * b): 
        a(a), b(b) {}

    int * a;
    int * b;
};

int a = 1, b = 2;
const int * aRef = &a;
const int * bRef = &b;
const T obj(aRef, bRef); // error

This is clearly not allowed, as the constructor accepts int *, not const int *. Is there a way to achieve the same effect, although if there is no intention to change the data in aand bin constthe class object T?

Edit Here is a slightly more complex example that is closer to the real problem. Imagine that I sequentially passed several large arrays int[](say, 1000 integers in a row), and I want to estimate the maximum number of elements in the kith position (that is, the current maximum is also 1000-int vector). When I pass const int *to the beginning of the incoming array, I create a struct

struct ArrayWithMax
{
public:
    ArrayWithMax(int * array) : array(array) {}
    void Max(const ArrayWithMax& rhs);

private:
    int * array;
}

ArrayWithMax::Max, obviously, will cycle through both arrays and assign the largest value ( max(this->array[k], rhs.array[k]) to the object array. I will skip the code for short.

, , ( max-array). const int *. , const ArrayWithMax const int *, .

+4
3

, :

const T obj(aRef, bRef);

, , . , int const* const, int const*.

, const , int* const, , .

, , - :

template<typename Type>
struct T {
    T(Type* a, Type* b): 
        a(a), b(b) {}

    Type* a;
    Type* b;
};

:

int a = 1, b = 2;
int const* aRef = &a;
int const* bRef = &b;
T<int const> obj(aRef, bRef);

Live demo

, const, :

T<int const> const obj(aRef, bRef);
+3

, . ArrayWithMax , int*, , int const *. non-mutable ArrayWithMax ArrayWithMax::Max(), . , , , vlad_tepesch , . , :

#include <iostream>
#include <algorithm>
#include <cstring>
#include <iterator>

using namespace std;

const size_t ARRAY_SIZE = 2;   // hardcoded for now; it could be 1000

template <typename T>
class ArrayWithMax
{
public:
    ArrayWithMax(T array) : array_(array){}

    // Max will accept any class, as long as it provides U::begin() const
    // Max will not be generated when type T is const.
    template <typename U>
    void Max(const U& rhs)
    {
        transform(begin(), end(), rhs.begin(), begin(),
            [] (auto a, auto b) { return max(a, b); } );
    }

    T begin() { return array_; }
    T end() { return array_+size(); }

    T begin() const { return array_; }
    T end() const { return array_+size(); }
    size_t size() const { return ARRAY_SIZE; }

private:
    T array_;
};

int main()
{
    // some data to test with
    int someArray[ARRAY_SIZE];
    someArray[0] = 1;
    someArray[1] = 2;
    int const * received = someArray;

    int someArray2[ARRAY_SIZE];
    someArray2[0] = 0;
    someArray2[1] = 8;
    int const * received2 = someArray2;

    // to store max
    int myStorage[ARRAY_SIZE];
    memset(myStorage, 0, sizeof(myStorage));

    int* aWithMax = myStorage;

    // first mutable ArrayWithMax with myStorage
    ArrayWithMax<int*> a(aWithMax);

    copy(a.begin(), a.end(), ostream_iterator<int>(cout, " "));
    cout << endl;

    // other ArrayWithMax with const int*
    ArrayWithMax<const int*> receivedArray(received);
    a.Max(receivedArray);

    copy(a.begin(), a.end(), ostream_iterator<int>(cout, " "));
    cout << endl;

    // and another
    ArrayWithMax<const int*> receivedArray2(received2);
    a.Max(receivedArray2);

    copy(a.begin(), a.end(), ostream_iterator<int>(cout, " "));
    cout << endl;
}

, , :

Luiss-Air:const luis$ g++-5.3.0 -std=c++14 ArrayWithMax.C 
Luiss-Air:const luis$ a.out
0 0 
1 2 
1 8 
Luiss-Air:const luis$

ArrayWithMax , std:: transform:

    // this does what you want to do with your class
    transform(aWithMax, aWithMax+ARRAY_SIZE, received, aWithMax,
        [] (auto a, auto b) { return max(a, b); });
+1

, :

struct CT
{
    CT(int const * a, int const * b) :
        a(a), b(b) {}

    int const * ca;
    int const * cb;
};

struct T : CT
{
    T(int * a, int * b) :
        CT(a, b) {}

    int * a() const { return const_cast<int *>(ca); }
    int * b() const { return const_cast<int *>(cb); }    
};

CT T T CT.

const T vs. T. . -ctor . const-ref, *a *b.

0

Source: https://habr.com/ru/post/1628214/


All Articles