Синтаксис, который вы запрашиваете, теоретически возможен с использованием введенных имен классов.Это заставит Foo::
разрешить конкретное, не связанное Foo<x>::
.Вот пример:
struct BaseFoo {
template<class K> static
auto& DeductInstance(const K&);
};
template <class T>
struct Foo {
static auto& Instance() {
static Foo foo{};
return foo;
}
};
template<>
struct Foo<void> : private BaseFoo {
using BaseFoo::DeductInstance;
};
template<typename K>
auto& BaseFoo::DeductInstance(const K&)
{
return Foo<K>::Instance();
}
using MakeFooAvailable = Foo<void>;
struct Dummy : MakeFooAvailable {
auto& bar() {
// Syntax working
return Foo::DeductInstance(234);
}
};
В классе Dummy
есть имя внедренного класса для базового класса Foo
, разрешающее его до Foo<void>
.Затем Foo<void>
делает доступным BaseFoo::DeductInstance
для разрешения имен в своей области.
Я бы посоветовал не использовать это решение, потому что оно умное.Умный вообще значит удивительный.Программисты не ожидают увидеть Foo
как не шаблон, когда он есть.Лучшее решение, которое я думаю, было бы:
auto& foo1 = Foo<int>::Instance(); //OK
Чем проще, тем лучше.