Явный конструктор копирования делает ошибку компиляции в c ++.Кто отвечает за кастинг? - PullRequest
0 голосов
/ 02 марта 2019

My Clion IDE показывает мне, что может быть проблема при передаче типа const double* в функцию, у которой есть параметр const A, когда A определен с двойным массивом, как показано ниже.

Когда второй конструктор A является явным, возникает ошибка компиляции, но когда второй конструктор A не является явным, все работает нормально.Я предполагал, что должен быть кастинг от const double* до const A, но я не уверен.Затем я отладил код и увидел, что был вызван только первый конструктор A.

Так почему же важно, если второй конструктор явно не равен?

class A {
public:
friend class B;
private:
    A(double v1, double v2): _x{v1, v2}{}
    explicit A(const double *arr2): _x{*arr2, *(arr2+1)}{}
    double _x[2];

};
class B {
private:
    A _b1, _b2;
    static double foo(const A &first, const A &second){
        return first._x[0]*second._x[1];
    }
public:
    B(): _b1(2.1, 2.2), _b2(1.2, 1.1){}
    B(double List[2][2]): _b1(List[0][0],List[0][1]), _b2(List[1][0], List[1][1]) 
  {}
    void Problem( const double* bArr, double* result) const{
        double goesTo=thisfunc();

        *result =foo(bArr, _b1)/goesTo; //this is where Clion states a possible problem
    }
    double thisfunc() const{

        return foo(_b1, _b2);
    }
};
int main() {
    double initArray[][2]={{2,1},{1,1}};
    B M(initArray);
    return 0;
} 

Ответы [ 2 ]

0 голосов
/ 03 марта 2019

Код в вопросе сложен, но проблема проста.

void f(const A&);
double data[] = { 1.0, 2.0 };
f(data); // error

Когда отмечен A(const double*) explicit, компилятору не разрешено использовать его для неявного преобразования data вобъект типа A.Чтобы использовать этот конструктор, код должен иметь явное преобразование:

f(static_cast<A>(data));

В конце концов, это то, что означает explicit.

0 голосов
/ 03 марта 2019

Похоже, вы передаете указатель bArr на ссылочный аргумент.Вы можете сначала разыменовать указатель:

*result =foo(*bArr, _b1)/goesTo;

Кроме того, я на 99% уверен, что именно это и есть в сообщении об ошибке.

Ответитьваш вопрос.Не существует неявного преобразования (приведения) из указателя в ссылку.Вы должны явно использовать оператор разыменования - с префиксом *.Конструктор копирования не является оператором приведения и не является оператором приведения.

Оператор приведения в классе T преобразует из T в какой-либо другой тип.Конструктор копирования копирует один экземпляр T в другой экземпляр T.Обычный конструктор с одним аргументом какого-то другого типа можно рассматривать как преобразование указанного другого типа в экземпляр типа T.

EDIT: Как указал Пит Беккер, это не исправляетпроблема как explicit A(const double *arr2) помечена как явная, что запрещает компилятору делать одно неявное преобразование, которое ему разрешено делать.Поэтому правильное решение состоит в том, чтобы напрямую создать A из bArr или пометить его как неявное

...