www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - IFTI in Eponymous Templates

reply jmh530 <john.michael.hall gmail.com> writes:
I was playing around with some Eponymous Templates. I had been 
under the impression that Implicit Function-Template 
Instantiation (IFTI) meant that you don't have to explicitly 
instantiate all functions. However, it seems like there are cases 
with eponymous templates with functions in them that you do. For 
instance, in the bar function below, I have to explicitly 
instantiate the inner function template.


template foo(T, U)
{
	T foo(T x, U y)
	{
		return x + cast(T)y;
	}
}

template bar(T)
{
	T bar(U)(T x, U y)
	{
		return x + cast(T)y;
	}
}

void main()
{
	int a = 1;
	long b = 2;
	auto x = foo(a, a);
	//auto y = bar(a, b); //error
	auto y = bar!(long)(a, b);
}
Jun 29 2016
next sibling parent Hiemlick Hiemlicker <HH reign.com> writes:
On Wednesday, 29 June 2016 at 18:59:19 UTC, jmh530 wrote:
 I was playing around with some Eponymous Templates. I had been 
 under the impression that Implicit Function-Template 
 Instantiation (IFTI) meant that you don't have to explicitly 
 instantiate all functions. However, it seems like there are 
 cases with eponymous templates with functions in them that you 
 do. For instance, in the bar function below, I have to 
 explicitly instantiate the inner function template.


 template foo(T, U)
 {
 	T foo(T x, U y)
 	{
 		return x + cast(T)y;
 	}
 }

 template bar(T)
 {
 	T bar(U)(T x, U y)
 	{
 		return x + cast(T)y;
 	}
 }

 void main()
 {
 	int a = 1;
 	long b = 2;
 	auto x = foo(a, a);
 	//auto y = bar(a, b); //error
 	auto y = bar!(long)(a, b);
 }
This seems like a bug?! U can clearly be deduced. The real question, is it needed? template bar(T, U) { T bar(T x, U y) { return x + cast(T)y; } }
Jun 29 2016
prev sibling parent reply ag0aep6g <anonymous example.com> writes:
On 06/29/2016 08:59 PM, jmh530 wrote:
 For instance, in the bar function below, I have to
 explicitly instantiate the inner function template.
[...]
 template bar(T)
 {
      T bar(U)(T x, U y)
      {
          return x + cast(T)y;
      }
 }

 void main()
 {
      int a = 1;
      long b = 2;
      auto x = foo(a, a);
      //auto y = bar(a, b); //error
      auto y = bar!(long)(a, b);
 }
You're explicitly instantiating the outer bar there, not the inner one. The inner one is instantiated via IFTI. You're explicitly setting T = long. U = long is set implicitly from the type of b. IFTI is defined to work on function templates. The outer bar is not a function template. It's a template for a function template. So no IFTI. Maybe IFTI could work on templates for (templates for ...) function templates. Someone would have to consider all the details, write up an improvement proposal, get it approved, and implement it.
Jun 29 2016
parent jmh530 <john.michael.hall gmail.com> writes:
On Wednesday, 29 June 2016 at 21:38:23 UTC, ag0aep6g wrote:
 You're explicitly instantiating the outer bar there, not the 
 inner one.
Yes, you're correct. I mixed up the inner/outer. I just thought it was something weird I had noticed.
Jun 29 2016