Да, вы можете создать шаблонный класс `Lazy`, который будет иметь первый аргумент явно заданным, а второй аргумент — параметром шаблона с умолчанием. Это позволит вам задать необходимую функциональность, связанную с `TFactory`, при этом сохранив возможность явно указывать тип для `Lazy`.
Ваш класс можно реализовать следующим образом:
```cpp
template <typename TFactory = DefaultValueFactory<Cursor>>
class Lazy final {
public:
using ResultType = Cursor;
Lazy(std::function<ResultType()> factory)
: factory_(factory) {}
ResultType get() {
if (!isInitialized_) {
value_ = factory_();
isInitialized_ = true;
}
return value_;
}
private:
std::function<ResultType()> factory_;
ResultType value_;
bool isInitialized_ = false;
};
```
Теперь, когда вы создаете экземпляр `Lazy` с типом `Cursor`, вы можете указать только второй аргумент, например:
```cpp
Lazy<> Arrow = [] { return Cursor(SDL_SYSTEM_CURSOR_ARROW); };
```
Или, если вам нужно явно указать фабрику:
```cpp
Lazy<MyCustomFactory> Arrow = [] { return Cursor(SDL_SYSTEM_CURSOR_ARROW); };
```
Что касается читаемости и контроля параметров шаблона, такой подход подойдет, если:
1. Вы всегда используете один и тот же тип для первого аргумента, что упрощает использование класса и предотвращает возможные ошибки с типами.
2. Вы хотите сохранить возможность использовать разные фабрики, если у вас есть инструменты для создания объектов и вам нужно это разнообразие.
Благодаря этому конструкция становится более понятной, поскольку вы явно разделяете параметры шаблона на два, и это может улучшить понимание кода другими программистами, особенно если они знают, что `T` будет всегда типом `Cursor`. Однако, как и везде, всё зависит от контекста использования и предпочтений команды разработчиков, поэтому важно учитывать конкретные требования вашего проекта.