#c #templates
#c #шаблоны
Вопрос:
Я вижу несколько похожих вопросов, но, похоже, они этого не понимают.
Я могу перегрузить функцию в шаблоне:
template <typename T> void foo(); // Called as e.g., foo<int>();
template <std::size_t I> void foo(); // Called as e.g., foo<2>();
Есть ли способ сделать что-то подобное с классом, где я могу иметь либо MyClass<int>
или MyClass<2>
?
Я не вижу способа сделать это. (Моя настоящая цель — иметь static constexpr
экземпляр вызываемого объекта, который действует как std::get
. В то std::get
время как шаблон используется для его параметра «индексирование» и для типа аргумента, я бы хотел создать тот, который вызывается сам по себе, поэтому myns::get<2>
и myns::get<int>
оба являются вызываемыми, а при вызове действуют как std::get<2>(tup)
и std::get<int>(tup)
соответственно.
Наивно надеяться, что что-то подобное сработает, но auto
это тип:
template <auto IndOrType>
constexpr auto get = [](autoamp;amp; tup) {
return std::get<IndOrType>(std::forward<decltype(tup)>(tup));
};
Я могу создать функцию получения, которая возвращает лямбда-выражение, но тогда она вызывается ()
как в myns::get<2>()(tup)
or myns::get<int>()(tup)
.
Ответ №1:
Вы могли бы специализировать класс, используя вспомогательный тип std::integral_constant<int,N>
. Хотя, к сожалению, это не совсем позволяет MyClass<2>
использовать синтаксис:
#include <type_traits>
template<typename T>
class MyClass
{
};
template<int N>
using ic = std::integral_constant<int,N>;
template<int N>
class MyClass<ic<N>>
{
};
int main()
{
MyClass<int> a;
MyClass<ic<2>> b;
}
Комментарии:
1. Правильно. Если бы только был способ сделать
2
неявное преобразование вic<2>
в этом контексте…2. Да, я надеялся, что он может автоматически соответствовать специализации, но, увы.
3. Кстати, я не совсем уверен в вашем предполагаемом варианте использования. Но, возможно, не может работать перегруженная функция
makeMyClass
? Вместо того, чтобы напрямую называть тип, позвольте перегруженной функции выполнять специализацию для любой версии MyClass .4. Я действительно просто надеялся синтаксически сделать
auto f = get<X>; f(t);
и заставить это действоватьstd::get<X>(t);
, что кажется естественным. Это кажется таким простым, но для этого я обнаружил, что чувствую, что это возможно, поэтому я решил, что это хороший вопрос для SO.5. Кажется, что шаблоны функций — это единственное, что может быть перегружено в главном параметре шаблона, поэтому в конечном итоге перегрузка может оказаться невозможной.