Скажем, у меня есть класс FunctionWrapper
, определенный как это:Запретить неявное преобразование, но разрешить инициализацию списка?
struct FunctionWrapper
{
FunctionWrapper(std::function<void()> f);
// ... plus other members irrelevant to the question
};
Я хотел бы, чтобы предотвратить неявные преобразования из std::function<void()>
в FunctionWrapper
, но позволяют построения FunctionWrapper
с помощью бандажа инициализации синтаксиса (то есть, используя список инициализации с одним аргументом). Другими словами, мне бы хотелось:
void foo();
void wrap(FunctionWrapper);
wrap(foo); // (1) error
wrap({foo}); // (2) OK
wrap(FunctionWrapper{foo}); // (3) OK
Есть ли способ достичь этого? То, как я определил класс выше, не так: это позволяет неявные преобразования, поэтому (1) компилируется.
Если добавить explicit
конструктору:
struct FunctionWrapper
{
explicit FunctionWrapper(std::function<void()> f);
// ... plus other members irrelevant to the question
};
это не помогает, так как это идет «слишком далеко» и Запрещает (2), а также (1).
Есть ли способ достичь «средней земли» и скомпилировать (2), пока (1) выдает ошибку?
Добавить явный конструктор, который принимает параметр 'std :: initializer_list'. –
вы можете использовать initializer_list, но тогда у вас будет только проверка времени на количество аргументов ... может быть, шаблон принимает const-массив и static_assert на размер шаблона ... но это просто уродливо – Hcorg
@Hcorg не будет [это] (http: /melpon.org/wandbox/permlink/0rFgVYD8XKYwVlC1) требуется инициализация двойной скобки? –