Возможно ли эмулировать шаблон?

#c #templates #type-inference

#c #шаблоны #вывод типа

Вопрос:

Возможно ли это каким-то образом? Я хочу, чтобы это включало передачу аргументов во время компиляции. Предположим, это только для удобства пользователя, поскольку всегда можно ввести реальный тип с помощью template<class T, T X> , но для некоторых типов, т. Е. функций-указателей на члены, это довольно утомительно, даже с decltype в качестве ярлыка. Рассмотрим следующий код:

 struct Foo{
  template<class T, T X>
  void bar(){
    // do something with X, compile-time passed
  }
};

struct Baz{
  void bang(){
  }
};

int main(){
  Foo f;
  f.bar<int,5>();
  f.bar<decltype(amp;Baz::bang),amp;Baz::bang>();
}
  

Можно ли каким-то образом преобразовать его в следующий?

 struct Foo{
  template<auto X>
  void bar(){
    // do something with X, compile-time passed
  }
};

struct Baz{
  void bang(){
  }
};

int main(){
  Foo f;
  f.bar<5>();
  f.bar<amp;Baz::bang>();
}
  

Комментарии:

1. @GMan: Обновлено, надеюсь, теперь это имеет больше смысла. 🙂

Ответ №1:

После вашего обновления: нет. В C такой функциональности нет. Самый близкий — это макросы:

 #define AUTO_ARG(x) decltype(x), x

f.bar<AUTO_ARG(5)>();
f.bar<AUTO_ARG(amp;Baz::bang)>();
  

Звучит так, как будто вам нужен генератор:

 template <typename T>
struct foo
{
    foo(const Tamp;) {} // do whatever
};

template <typename T>
foo<T> make_foo(const Tamp; x)
{
    return foo<T>(x);
}
  

Теперь вместо того, чтобы прописывать:

 foo<int>(5);
  

Вы можете сделать:

 make_foo(5);
  

Чтобы вывести аргумент.

Комментарии:

1. Это еще более полезно в C 0x, где вы можете использовать, auto my_foo(make_foo(5)); даже не называя тип foo<int> полностью.

2. если передача аргумента в функцию вызывала бы беспокойство, тогда asker мог бы напрямую использовать f.bar(5); и объявить метод просто как template<typename T>void bar(T amp;X); . Какая польза от вашего make_foo() ?

3. @iammilind: Это было старое предположение к его вопросу, прежде чем он прояснил.

4. @iamm: вывод аргумента шаблона работает только с функциями, а не с классами.

5. @Jonathan.: Я не думаю, что многие вещи в языке работают по умолчанию, не говоря уже о auto расширении до двух отдельных параметров шаблона.

Ответ №2:

Он был добавлен в C 17, теперь вы можете писать

 template<auto n> struct B { /* ... */ };
B<5> b1;   // OK: non-type template parameter type is int
B<'a'> b2; // OK: non-type template parameter type is char
  

Смотрите http://en.cppreference.com/w/cpp/language/template_parameters , пункт 4 раздела Нетиповых параметров шаблона

Ответ №3:

Это НЕВОЗМОЖНО. Единственный способ добиться этого — передать аргумент в функцию:

 struct Foo{
  template<class T> void bar(Tamp; X) {}
};
  

А затем вызвать функцию как,

 f.bar(5);
f.bar(amp;Baz::bang);