Это элегантный способ перегрузить статическую функцию-член, которая предоставляет тот же интерфейс, что и нестатическая функция-член?

Рассмотрим следующий неклассовый шаблон, который имеет переменную шаблона и использует псевдоним шаблона и автоматический вывод типа.

template<typename T>
using Type = T;

using TypeA = Type<int>;
using TypeB = Type<double>;

class Foo {
private:
    template<typename T>
    static Type<T> type_;
public:
    template<typename T>
    explicit Foo( Type<T> type ) { type_<T> = type; }

    // non static member
    template<typename T>
    auto bar() { return type_<T>; }

    // static member
    template<typename T>
    static auto bar(T _x_ = 0) { return type_<T>; }
};

И программа, которая его использует:

// has to be defined in some cpp file.
template<typename T>
Type<T> Foo::type_;

int main() {
     TypeA a{ 7 };
     TypeB b{ 3.41 };

     Foo f1( a );
     Foo f2( b );

     auto x = Foo::bar<TypeA>();
     auto y = Foo::bar<TypeB>();

     std::cout << "static auto f1: " << x << '\n';
     std::cout << "static auto f2: " << y << '\n';

     std::cout << "member f1: " << f1.bar<TypeA>() << '\n';
     std::cout << "member f2: " << f2.bar<TypeB>() << '\n';

     return 0;
};

Вывод

static auto f1: 7
static auto f2: 3.41
member f1: 7
member f2: 3.41

В объявлении класса; Я использую параметр T в статической версии и устанавливаю его по умолчанию равным 0, чтобы его можно было вызывать без каких-либо параметров. Если это не добавить, то нельзя будет перегрузить статическую и нестатическую функцию-член, у которой нет аргументов или одинаковые аргументы для списка параметров.

Будет ли это считаться быстрым исправлением или взломом, или это возможный способ предоставить один и тот же тип интерфейса как для статической, так и для нестатической функции-члена с тем же именем и функциональностью?

Аргумент или параметр функции является фиктивным аргументом, который абсолютно ничего не делает с внутренним значением.

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

Поэтому я думаю, что настоящий вопрос должен был быть следующим: что касается переменных членов шаблона и того, что они должны быть статическими, каков предпочтительный способ доступа к ним через функцию-член: через статический или нестатический, или нет предпочтения и этого выбора остается на усмотрение программиста?

Еще одна последняя вещь; есть ли какие-либо непредвиденные проблемы, которые могут привести к будущим последствиям с этим типом шаблона проектирования - интерфейсом?


person Francis Cugler    schedule 20.07.2019    source источник
comment
Вы находитесь в лабиринте извилистых маленьких проходов, похожих друг на друга.   -  person Pete Becker    schedule 21.07.2019
comment
Статическая функция-член может быть вызвана с использованием синтаксиса f1.bar<TypeA>(). Нет необходимости объявлять нестатическую версию (если вы не хотите создавать указатель на член функции).   -  person cpplearner    schedule 21.07.2019
comment
Я даже не понимаю, что ты здесь делаешь. Тип возвращаемого значения будет Type<Type<int>> или Type<Type<double>>. Этого ты вообще хочешь? Если да, то это кажется очень странным.   -  person Omnifarious    schedule 21.07.2019
comment
Какой компилятор вы используете? Я получаю неоднозначные ошибки типа вызова, когда пытаюсь его скомпилировать.   -  person 1201ProgramAlarm    schedule 21.07.2019
comment
Возможный дубликат вызов статического метода-члена C++ для экземпляра класса. Или, возможно, нет, в зависимости от предполагаемого использования того же типа интерфейса.   -  person JaMiT    schedule 21.07.2019
comment
В качестве примечания; Я знал о концепциях псевдонимов шаблонов и переменных шаблонов, но никогда не использовал их раньше. Это была просто экспериментальная практика. Знакомство с синтаксисом и как правильно его реализовать. Когда я начал работать с шаблоном переменной внутри класса, компилятор заставлял меня объявлять его как статический член. Я смог написать функции, которые обращались бы к нему либо через статический, либо не статический, что привело меня к вышеизложенному. Я просто хотел ясности в рассуждениях.   -  person Francis Cugler    schedule 21.07.2019
comment
Я думаю, что то, как я задал свой вопрос, немного вводит в заблуждение, поскольку я не уточнил, что это в основном связано с использованием псевдонимов шаблонов и переменных шаблонов. У меня больше общего с ними, чем со статическими и нестатическими функциями, и я просто смог создать версию обоих, чтобы делать одно и то же, но дать любому из них перегруженный фиктивный аргумент по умолчанию, который ничего не делает внутри. Я никогда не упоминал в вопросе, что T _x_ = 0 в объявлении функции абсолютно ничего не делает с внутренними значениями. Это просто фиктивный аргумент.   -  person Francis Cugler    schedule 21.07.2019
comment
@JaMiT Просто для доступа к внутреннему элементу переменной шаблона и возврата текущего значения в определенный момент времени ... эти функции не изменяют значение.   -  person Francis Cugler    schedule 21.07.2019
comment
@ 1201ProgramAlarm Я использую Visual Studio 2017, скомпилированную как C++ 17.   -  person Francis Cugler    schedule 21.07.2019
comment
@Omnifarious Я начинаю экспериментировать с использованием Variable Templates и Template Aliasing, поскольку я никогда их не использовал, так что это был тренировочный код, чтобы понять правильный синтаксис и их использование. Я просто ищу угловые случаи, ловушки и т. Д.   -  person Francis Cugler    schedule 21.07.2019
comment
@FrancisCugler Ваш измененный вопрос больше не имеет ничего общего с шаблонами. Это просто вопрос о том, должен ли метод доступа для члена данных static также быть static. В этом случае дубликат, вероятно, Преимущество использования статической функции-члена вместо эквивалентной нестатической функции-члена?   -  person JaMiT    schedule 22.07.2019


Ответы (1)


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

Не существует правильного способа достичь неправильной цели. Кроме того, ваша версия не предоставляет такой же интерфейс. Нестатическая версия требует явного аргумента шаблона, тогда как статическая версия может использовать вывод, как в f1.bar(1). Я не уверен, что рекомендую использовать дедукцию в этом случае (потому что код более загадочный), но такая возможность предоставляется. Ваша неправильная цель даже не достигнута.

Если функции имеют одинаковый функционал (как в вашем примере), то нестатическая версия — это бессмысленные накладные расходы. Предоставьте только статическую версию, и если кто-то захочет вызвать ее из объекта, все в порядке.

Если функции не имеют одинакового функционала (может быть, ваш пример был слишком упрощен?), то давать им одинаковые имена — это Плохая Идея. Это включает в себя случай, когда нестатическая версия может возвращать разные значения в зависимости от *this. По крайней мере, в этом случае статическая версия должна быть переименована во что-то вроде bar_no_object(), чтобы отличить ее от версии, зависящей от объекта.

Еще одна последняя вещь; есть ли какие-либо непредвиденные проблемы, которые могут привести к будущим последствиям с этим типом шаблона проектирования - интерфейсом?

Ну, в общем, вы настраиваете себя на массу путаницы. Все остальные будут ожидать, что Foo::bar() и Foo{}.bar() вызовут одну и ту же (статическую) функцию, а вы пытаетесь это сломать.

Обратите внимание на сообщения вашего компилятора. Это ожидание всех остальных является причиной того, что вы не смогли «перегрузить статическую и нестатическую функцию-член, у которой нет аргументов или одинаковые аргументы для списка параметров». Вы пытались создать двусмысленность, и компилятор остановил вас. По уважительной причине. Прежде чем спрашивать действителен ли ваш обходной путь, возможно, вам следовало спросить, почему компилятор остановил вас. ?

person JaMiT    schedule 21.07.2019
comment
Я понимаю, почему компилятор не позволил мне перегрузить статическую и нестатическую функцию с одинаковыми сигнатурами. Я просто экспериментировал с шаблонами переменных и псевдонимом шаблона, и когда я начал добавлять шаблон переменной в качестве члена класса, это вынуждало меня объявлять переменную как статическую. Мне удалось написать функцию доступа для извлечения значения как в статической, так и в нестатической версиях. Затем я понял, что если я передам статической версии аргумент dummy, который ничего не делает внутри, то я смогу получить значение из одной или обеих функций. - person Francis Cugler; 21.07.2019
comment
@FrancisCugler Другими словами, вы обнаружили, что нестатическая версия может делать все то же, что и статическая версия, но может использоваться в меньшем количестве контекстов (строгое подмножество контекстов, в которых может использоваться статическая версия). Он строго уступает статической версии. Нет нет причин хранить его. И все же вы хотели сохранить его. В результате получился беспорядочный код без какой-либо пользы. Не делай этого. - person JaMiT; 22.07.2019