LINUX.ORG.RU

запутался со специализацией шаблонного метода для шаблонного класса

 ,


0

2

Имеется что-то вроде такого шаблона:

template<int n>
struct foo_t{
	
	template<int m=n>
	int bar(){
		cout<<"call foo<"<<m<<">"<<endl;
		return m+bar<m-1>();
	};
};
И тут нужно явно специализировать вызов для bar<0>, а каким образом?

★★★★★

Последнее исправление: thunar (всего исправлений: 1)

Может тебе скорее надо специализовать случай bar<0>? Иначе бесконечное инстанцирование метода bar выходит

spectral1989
()
  template<int n>
  class bar {...};

  template<>
  class bar<0> {...};
Dudraug ★★★★★
()
Ответ на: комментарий от spectral1989

Только по стандарту (и многим реализациям компиляторов) это невозможно. Для свободных функций - да, для мемберов - нет.

Dudraug ★★★★★
()

Тебе надо что-то вроде


template<unsigned int> struct foo;

template<>
struct foo<0>
{
  int bar(){ return 0;}
};

template<unsigned int n> 
struct foo : public foo<n-1>
{
   int bar() {return n + this->foo<n-1>::bar();}
};
Dudraug ★★★★★
()
Последнее исправление: Dudraug (всего исправлений: 1)
Ответ на: комментарий от thunar

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

Dudraug ★★★★★
()
Ответ на: комментарий от Dudraug

Шаблонные функции по идее нельзя специализировать, но если сделать фейковй аргумент - их по идее можно перегрузить.

типа

template<int m=n>
	int bar(std::array<int, m>* unused_null){
		cout<<"call foo<"<<m<<">"<<endl;
                std::array<int, m-1>* fake_arg = nullptr;
		return m+bar(fake_arg);
	};

	int bar(std::array<int, 0>* unused_null){
            cout<<"no recursion"<<endl;
            return 0;
	};

GPFault ★★
()
Ответ на: комментарий от GPFault

Вообще можно, но не внутри тела класса. То есть в отдельном cpp. И вроде только полную специализацию, partial нельзя, поэтому я предполчитаю делать специализации классов. Но там свои огрничения. Комитет стандартизации что-то переусложнил вопреки логики эту тему с специализациями.

Dudraug ★★★★★
()

В тегах не указан стандарт. Если доступен С++17, можно просто явно проверять терминальный вызов «if constexpr»'ом.

seiken ★★★★★
()
Ответ на: комментарий от seiken

К сожалению, ограничен 14м стандартом.

thunar ★★★★★
() автор топика
Ответ на: комментарий от Dudraug

А через enable_if как ни будь такое не провернуть?

thunar ★★★★★
() автор топика
template<int n>
struct foo_t
{
  template<int m, typename std::enable_if<m != 0, int>::type* = nullptr>
  int bar()
  {
    return m + bar<m - 1>();
  }

  template<int m, typename std::enable_if<m == 0, int>::type* = nullptr>
  int bar()
  {
    return 0;
  }
};
Ower
()
template<int m>
int bar_impl([[maybe_unused]] int n)
{
	return m + bar_impl<m-1>(n);
}

template<>
int bar_impl<0>([[maybe_unused]] int n)
{
	return 0;
}

template <int n>
struct Foo {
	template <int m = n>
	int bar()
	{
		return bar_impl<m>(n);
	}
};

AlexVR ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.