Страницы

Поиск по вопросам

воскресенье, 8 марта 2020 г.

Явное приведение типов и lexical_cast

#cpp #boost


Пример кода:

#include 
#include 

struct A
{
    int a;
    explicit operator std::string() {
        return "<" + std::to_string(a) + ">";
    }

};

void f(std::string s) {
    std::cout << s << std::endl;
}

int main()
{
    A a {1};
    f(static_cast(a));
    f(std::string(a));
    f((std::string)a);
    // f(boost::lexical_cast(a));
    return 0;
}


Вопроса 2:

1) Можно ли запретить приведение типов в С-стиле, так, чтобы на вызов f(std::string(a))
или f((std::string)a) компилятор ругался, а f(static_cast(a)) работало?

2) Как "научить" срабатывать вызов f(boost::lexical_cast(a))?
    


Ответы

Ответ 1



Что касается запрета приведения в стиле C, могу только посоветовать посмотреть в сторону опций компилятора. В GCC, например, можно добавить флаги -Wold-style-cast и -Werror, тогда приведение в стиле C будет вызывать предупреждение, а предупреждения будут трактоваться как ошибки. С boost::lexical_cast все просто, нужно добавить специализацию шаблона. Ваш пример примет такой вид: #include #include #include struct A { int a; explicit operator std::string() const{ return "<" + std::to_string(a) + ">"; } }; namespace boost{ template<> std::string lexical_cast(const A& arg){ return std::string(arg); } }; void f(std::string s) { std::cout << s << std::endl; } int main() { A a {1}; f(static_cast(a)); f(std::string(a)); f((std::string)a); f(boost::lexical_cast(a)); return 0; }

Ответ 2



Сообразил некое костыльное решение для запрета преобразований без static_cast: #include #include template T my_cast(X&& x) { return static_cast(x); } #define static_cast my_cast struct A { int a; private: explicit operator std::string() const { return "<" + std::to_string(a) + ">"; } template friend T my_cast(X&& x); }; void f(std::string s) { std::cout << s << std::endl; } int main() { A a {1}; f(static_cast(a)); // ok f(std::string(a)); // error f((std::string)a); // error return 0; }

Комментариев нет:

Отправить комментарий