явный конструктор c ++, не блокирующий преобразование double в int - PullRequest
1 голос
/ 12 февраля 2020

У меня есть конструктор для класса C из int и один из double.

Я позволяю первому выполнять неявное преобразование типов, но блокирую второй с помощью явного ключевого слова.

, но К сожалению, неявное преобразование типа double в int происходит .. Могу ли я как-то его заблокировать?

Вот упрощенный пример

//g++  5.4.0
#include <iostream>
using namespace std;

class C{
    int* tab;
    public:
    C():tab(nullptr){ cout<<"(void)create zilch\n"; }
    C(int size):tab(new int[size]){ cout<<"(int)create " << size << "\n"; }
    explicit C(double size):tab(new int[(int)size]){ cout<<"(double)create " << size << "\n"; }
    ~C(){ if(tab) {cout<<"destroy\n"; delete[] tab;} else cout <<"destroy zilch\n"; }
};    

int main()
{
    cout << "start\n";
    {
        C o1(1);
        C o2 = 2; //ok, implicit conversion allowed
        C o3(3.0);
        C o4 = 4.0; //ko, implicit conversion to double blocked... but goes to int 
    }
    cout << "stop\n";
}

//trace 
//
//start
//(int)create 1
//(int)create 2
//(double)create 3
//(int)create 4
//destroy
//destroy
//destroy
//destroy
//stop

Ответы [ 2 ]

1 голос
/ 12 февраля 2020

Вы можете попробовать заменить конструктор C (int) на конструктор, использующий черту включающего типа, например,

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

class C{
    int* tab;
    public:
    C():tab(nullptr){ cout<<"(void)create zilch\n"; }
    template<typename I, typename = typename enable_if<is_integral<I>::value>::type>
    C(I size):tab(new int[size]){ cout<<"(int)create " << size << "\n"; }
    explicit C(double size):tab(new int[(int)size]){ cout<<"(double)create " << size << "\n"; }
    ~C(){ if(tab) {cout<<"destroy\n"; delete[] tab;} else cout <<"destroy zilch\n"; }
};

int main()
{
    cout << "start\n";
    {
        C o1(1);
        C o2 = 2; //ok, implicit conversion allowed
        C o3(3.0);
        C o4 = 4.0; //ko, implicit conversion to double blocked... but goes to int
    }
    cout << "stop\n";
}

Это приведет к ошибке, подобной этой:

test.cpp: In function ‘int main()’:
test.cpp:22:16: error: conversion from ‘double’ to non-scalar type ‘C’ requested
         C o4 = 4.0; //ko, implicit conversion to double blocked... but goes to int
                ^
0 голосов
/ 12 февраля 2020

Хорошо! Eljay получил это быстрее в комментариях, но вот последний код, который даст вам ошибку компиляции при попытке неявно использовать double

#include <iostream>
using namespace std;

class C{
    int* tab;

public:
    //THE TRICK: block any implicit conversion by default
    template <class T> C(T) = delete;

    C():tab(nullptr){ cout<<"(void)create zilch\n"; }
    C(int size):tab(new int[size]){ cout<<"(int)create " << size << "\n"; }
    explicit C(double size):tab(new int[(int)size]){ cout<<"(double)create " << size << "\n"; }
    ~C(){ if(tab) {cout<<"destroy\n"; delete[] tab;} else cout <<"destroy zilch\n"; }
};

int main()
{
    cout << "start\n";
    {
        C o1(1);
        C o2 = 2; //ok, implicit conversion allowed
        C o3(3.0);
        C o4 = 4.0; //ko, implicit conversion to other types deleted
        C o5 = (C)5.0; //ok. explicit conversion
    }
    cout << "stop\n";
}
...