Given the following situation:
template<typename T>
class Foo
{
private:
Foo(/*args*/);
public:
static Foo<T> create(/*args*/);
template<typename U>
Foo<U> bar(/*args*/);
};
I have this create
function for users of this class to use instead of its constructor. The bar
function needs to instantiate a Foo
but with a different template type. This bar
function can't use create
because its arguments are not suited for it. This doesn't compile because, AFAIU, Foo<T>
and Foo<U>
are plainly different types and they can't see each other's private functions just like any two unrelated classes can't.
I've resorted to having the constructor public
but is there a way out given the goal of enforcing instantiation through the create
function exclusively by users of this class?
Edit: minimal reproducible example and compiler's output:
template<typename T>
class Foo
{
private:
Foo(/*args*/)
{}
public:
static Foo<T> create(/*args*/)
{
return Foo<T>();
}
template<typename U>
Foo<U> bar(/*args*/)
{
return Foo<U>();
}
};
int main()
{
auto fi = Foo<int>::create();
auto ff = fi.bar<float>();
(void)ff;
return 0;
}
main.cpp:17:16: error: calling a private constructor of class 'Foo<float>'
return Foo<U>();
^
main.cpp:24:18: note: in instantiation of function template specialization 'Foo<int>::bar<float>' requested here
auto ff = fi.bar<float>();
^
main.cpp:5:5: note: declared private here
Foo(/*args*/)