Re[3]: Специализация метода. Нужно устранить ошибку
От: vopl Россия  
Дата: 23.08.22 16:41
Оценка: 6 (1)
Здравствуйте, SVV, Вы писали:

SVV>Здравствуйте, vopl, Вы писали:


V>>Здравствуйте, SVV, Вы писали:


SVV>>>как правильно написать специализацию метода?


V>>Напрямую — никак. Это будет частичная специализация, язык такое не позволяет. Но, можно нечто похожее организовать через SFINAE или через концепты

SVV>...
V>>Еще можно вынести специализацию в другой класс и его уже специализировать, а foo оставить обобщенным..

SVV>А как подобное провернуть с конструктором? Проблема с вызовом такого конструктора:

SVV>
SVV>template<typename T>
SVV>struct STest4
SVV>{
SVV>  template<typename H> STest4() requires is_same_v<H, TypeH1> { cout << "ctor(TypeH1)" << endl; }
SVV>  template<typename H> STest4() requires is_same_v<H, TypeH2> { cout << "ctor(TypeH2)" << endl; }
SVV>  ...
SVV>};

SVV>STest4<float> st5_1<TypeH1>();//warning C4930: 'STest4<float> st5_1(void)': prototyped function not called (was a variable definition intended?)
SVV>STest4<float> st5_2<TypeH2>();//warning C4930: 'STest4<float> st5_1(void)': prototyped function not called (was a variable definition intended?)
SVV>


SVV>код компилируется, но конструктор не вызывается.


Не вызывается, потому что st5_1 и st5_2 — это не объявления объектов, это такие функции. Примерно как тут https://cplusplus.com/doc/tutorial/classes/ , поищи там по слову oops

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

using TypeH1 = int;
using TypeH2 = char;

template <class T> struct Tag{};

template<typename T>
struct STest4
{
  template<typename H> STest4(Tag<H>) requires std::is_same_v<H, TypeH1> { std::cout << "ctor(TypeH1)" << std::endl; }
  template<typename H> STest4(Tag<H>) requires std::is_same_v<H, TypeH2> { std::cout << "ctor(TypeH2)" << std::endl; }
};

int main(int c_argc, char* c_argv[])
{
    STest4<float> st5_1{Tag<TypeH1>{}};
    STest4<float> st5_2{Tag<TypeH2>{}};
    return 0;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.