перегрузка преобразования не-члена в оператор bool - PullRequest
6 голосов
/ 28 марта 2012

Я пытаюсь написать оператор преобразования bool для std :: bitset

Я пытался:

template<size_t size>
operator bool(std::bitset<size> & b)
{
    return b.any();
}

, но я получил

error C2801: 'mynamespace::operator bool' must be a non-static member

из моего визуала-studio.

Но когда я смотрю объяснение C2801 , оно ничего не говорит об операторах преобразования (только об =, ->, [], ())

Итак,возможно ли как-то написать «Преобразование std :: bitset в оператор bool?»

(я не могу вызвать b.any() в моих операторах if, потому что тот же код должен выполняться при замене std :: bitsetс unsigned или чем-то

typedef std::bitset<x> Bitset;
//typedef unsigned Bitset;

, поэтому идеальный синтаксис будет выглядеть так:

Bitset b = whatewer;
if(b)
    doStuff();

)

Если эта перегрузка невозможна, какой метод рекомендуется использовать?

пока я использую это как:

if(b == Bitset(0))
    doStuff(); 

, но мне это не нравится.

Спасибо

Ответы [ 4 ]

6 голосов
/ 28 марта 2012

Как говорится в сообщении об ошибке, оператор преобразования должен быть нестатическим членом класса.Это правда.

Я не могу вызвать b.any () в моих операторах if, потому что тот же код должен выполняться, когда std :: bitset заменяется на unsigned или что-то в этом роде.

Если это ваша проблема, вы можете использовать перегрузку функции и вызвать ее, передав аргумент, который вернет логическое значение:

template<typename T>
bool to_bool(T const & b)
{
    return b; //implicit conversion (if allowed) for all other types
}

template<size_t N>
bool to_bool(std::bitset<N> const & b)
{
    return b.any();
}

, а затем использовать его как:

if (to_bool(whatever)) 
{
}

Это вызовет правильную перегрузку.Если тип whatever равен std::bitset<N>, будет вызвана вторая перегруженная функция, или же будет вызвана первая.

5 голосов
/ 28 марта 2012

§12.3.2 / 1: «Функция члена класса X с именем вида [...] определяет преобразование из X в указанный тип ...» (C++ 11 использует тот же номер раздела и почти такую ​​же формулировку, добавляя только то, что функция не принимает параметров).

Другим возможным способом определения преобразования является конструктор (§12.3.1), которыйочевидно, член класса.

Короче говоря, да, преобразования всегда должны быть определены как функции-члены.

Один из способов сделать то, что вы хотите, - написать обертку вокруг std::bitsetкоторый обеспечивает преобразование, о котором вы заботитесь:

template <int size>
class mybitest {
    std::bitset<size> bits;
public:
    operator bool() { return bits.any(); }
}

Но если вы решите это сделать, вам нужно будет написать функции пересылки практически для всех фрагментов bitset, которые вы используете (ctors, assignment)и т. д.)

2 голосов
/ 28 марта 2012

Стандарт немного неясен в этом (12.3.2):

A функция-член класса X , не имеющая параметров с именем вида [...] указывает преобразование из X в тип, указанный в ID-типа-преобразования.Такие функции называются функциями преобразования.Тип возврата не может быть указан. Если функция преобразования является функцией-членом , тип функции преобразования (8.3.5) - это «функция, не принимающая параметр, возвращающий идентификатор типа преобразования».

Первое предложение, по-видимому, подразумевает, что только функции-члены могут быть функциями преобразования, но я не уверен, какова цель условного "если функция преобразования является функцией-членом".Я бы взял первое предложение как обязательное и заключил, что функция преобразования должна быть функцией-членом.

0 голосов
/ 29 сентября 2018

в случае, если это кому-то поможет, вы можете вместо этого предоставить оператор not *

template<size_t size>
operator !(std::bitset<size> & b)
{
    return !b.any();
}

и использовать его так, используя идиому !!:

if (!!whatever)
{
}

, все еще не идеальную, но немного ближе, я думаю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...