2016-09-22 2 views
9

Рассмотрим класс b с двумя перегруженными методами foo:`using` только некоторые Перегрузки базового класса

struct b { 
    void foo(float) {} 
    void foo(const char *) {} 
}; 

Если я получить dprivate ют от b, я могу use using to expose b's foo:

struct d : private b { 
    using b::foo; 
}; 

Однако это подвергает все перегрузки. Есть ли способ разоблачить только один из них (скажем, float)? Например, в следующем, я хотел бы последнюю строку на провал компиляции:

d t; 
t.foo(3.13); // d should have this overload 
t.foo("hello"); // d shouldn't have this overload 

Я пробовал различные способы написания

using b::<i mean only void foo(float), dammit!> 

, но не мог получить любой из них компиляции.

Кроме того, очевидно, что можно определить в d только требуется перегрузка вызова перегрузки b «s

struct d : private b { 
    void foo(float f) { b::foo(f); } 
}; 

, но вопрос в том, если это возможно сделать это сжато только using.

+4

№ [_] (https://youtu.be/YjiTAkKhG28?t=158) –

+1

@ N.m. Хорошо, спасибо. –

+0

Почему бы вам не использовать реальные классы C++? – acornagl

ответ

8

Нет, это невозможно. Объявление using, как и любая другая декларация, работает по именам .

using b::foo; вводит имяfoo в сферу, содержащую Декларацию, такое, что оно относится к тому, что b::foo относится. Имя b::foo относится к «семейству» перегруженных функций, поэтому после использования-объявления имя foo относится к тому же.

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

struct d : private b { 
    void foo(float f) { b::foo(f); } 
}; 
+0

Спасибо за объяснение, что это имя основано. –

5

Как отметил @Angew в his answer, с использованием декларации вводит имена пространство имен.
Из-за этого, вы не можете выбрать только предпочтительные из них, но вы все еще можете сделать наоборот и = delete те, которые вы не хотите подвергать:

struct B { 
    void f() { } 
    void f(int) { } 
    void f(int, char) { } 
}; 

struct D: B { 
    using B::f; 
    void f(int) = delete; 
}; 

int main() { 
    D d; 
    d.f(); 
    d.f(0, 'c'); 
    // this won't work 
    // d.f(0); 
} 

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


Отсюда следует комментарий, сделанное @Yakk, которое стоит процитировать в ответ:

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

Это правильно, если решение выше работает для ОП, в основном зависит от реальной проблемы.
Я не могу сказать, что, но все-таки это жизнеспособное решение для некоторых случаев

+0

Интересная идея - спасибо! –

+0

@AmiTavory Это жизнеспособное решение, если функции, подлежащие удалению, являются небольшим числом. Если у вас 100 перегрузок, и вы хотите выставить только один или два из них, я бы предпочел использовать упомянутую функцию батута, и все. ;-) – skypjack

+0

Жаль, что я не смог ответить на оба ответа :-( –

Смежные вопросы