Упрощение вызовов статических методов шаблона класса, когда тип можно вывести из аргумента

У меня есть шаблон класса, а внутри него статический метод, входным аргументом которого является сам класс. Например:

#include <iostream>

template <typename T>
class A
{
public:
    A( const T& t ) : val(t) {}
    static bool IsValid( const A<T>& a ) { return (bool)a.val; }

private:
    T val;
};

int main()
{
    A<int> a( 5 );

    std::cout << A<int>::IsValid( a ) << "\n";   // <---
    return 0;
}

Я считаю, что строку 18 (отмеченную <---) очень неудобно писать снова и снова. Интересно, почему я не могу назвать свой метод как A::IsValid( a ), учитывая, что тип T можно легко вывести из входных данных a? Есть ли способ написать это по-другому, чтобы это было возможно?

Ближайший вопрос SO, который я нашел, был: Как вызвать статический метод шаблона класса без указания экземпляра?, но этот вопрос по своей сути отличается, поскольку у него нет аргументов, из которых можно было бы вывести тип.

потому что это невозможно вывести. A<T> есть метод IsValid(A<T>), но обратное неверно. IsValid(A<U>) может быть методом некоторых A<V>.

463035818_is_not_an_ai 15.04.2024 10:43

вы можете сделать это бесплатной функцией

463035818_is_not_an_ai 15.04.2024 10:44

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

Passer By 15.04.2024 10:52

Зачем писать A::IsValid(a), если можно написать a.isValid()?

Botje 15.04.2024 10:55

@Botje: потому что в реальном коде аргумент a на самом деле имеет тип shared_ptr<A<T>>, поэтому первое, что делает IsValid, — это проверяет сам указатель на nullptr .

Blabba 15.04.2024 11:08

Почему isValid — статическая функция? По названию я бы заподозрил, что это функция-член. Также аргументы выглядят точно так же, как this. Поэтому мне интересно: почему вы вообще сделали эту функцию статической? Ваш комментарий выше - плохое объяснение. Ваш способ адресации nullptr является излишним.

Marek R 15.04.2024 11:40
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Нет, это невозможно.

Сначала учтите, что только CTAD (вывод аргументов шаблона класса) выводит аргументы шаблона для шаблонов классов, которые собираются быть созданы на основе типов переданных аргументов функции. Однако, когда вы вызываете статический метод, ни один объект не создается.

Далее учтите, что A<U> можно специализировать на наличии члена IsValid(const A<V>&). Другими словами, между T типа аргумента IsValid(const A<T>&) и T в A<T>::IsValid не существует отношения 1 к 1. Например:

template <> class A<double> {
    static bool IsValid(const A<int>& a) { return true; }
};

Теперь не было бы возможности определить, какой экземпляр A требуется при вызове A::IsValid( A<int>{} ). Это вызов метода A<int> или A<double>? Имеет ли значение, что этот метод является членом класса? Это подводит меня к...

Вы можете написать бесплатную функцию:

 auto IsValid(const auto& a) { 
    return decltype(a)::IsValid(a);
 }

Или сделайте это нестатической функцией-членом.

Другие вопросы по теме