У меня есть шаблон класса с конструктором, в котором я хочу явно запретить использование любого типа за пределами четко определенного списка, например:
template<typename Anything>
class MyClass
{
public:
MyClass(int &);
MyClass(float &);
MyClass(Anything &) = delete;
}
Тем не менее, так как код для целое число и двойной версии идентичны и отличаются только типом, я бы хотел определить его с помощью шаблонной версии, например:
template<typename Anything>
MyClass<Anything>::MyClass(Anything &var)
{
/* Code that operates over var */
...
}
вместо того, чтобы фактически дублировать код для обоих допустимых конструкторов.
Однако, когда я попытался сделать это, я получил:
error: redefinition of 'MyClass<Anything>::MyClass(Anything&)'
Это работает, удаляя «= удалить».
Есть ли способ использовать шаблон для определения функции, но без явного разрешения получать больше типов, чем те, которые также описаны явно?
Я проверил Как я могу предотвратить неявные преобразования в шаблоне функции? а также Почему я могу предотвратить неявные преобразования для примитивов, но не для пользовательских типов?, но их проблемы, кажется, не эквивалентны текущей.
Большое спасибо.
ОБНОВЛЕНИЕ: Используя gcc-4.8.5, это работает !!! Даже с = удалить ключевое слово включено.
Проблема с вашим определением в том, что вы пытаетесь реализовать ту функцию, которую вы пометили = delete
,
Вы на самом деле хотите другой шаблон функции, который работает с обоими int
а также float
, Вы можете достичь этого, сначала определив IntOrFloat
сказуемое:
template <typename T>
using IntOrFloat = std::bool_constant<
std::is_same_v<T, int> || std::is_same_v<T, float>>;
Затем вы можете определить два однозначных конструктора, которые используют std::enable_if_t
чтобы проверить, выполняется ли предикат типом, переданным пользователем:
class MyClass
{
public:
template <typename T,
std::enable_if_t<IntOrFloat<T>{}>* = nullptr>
MyClass(T&);
template <typename Anything,
std::enable_if_t<!IntOrFloat<Anything>{}>* = nullptr>
MyClass(Anything&) = delete;
};
Пример использования:
int main()
{
int v0 = 0;
float v1 = 0.f;
const char* v2 = "igijsdg";
MyClass x0{v0}; // OK
MyClass x1{v1}; // OK
MyClass x2{v2}; // Error
}
Других решений пока нет …