Amir Jalilifard
Amir Jalilifard

Reputation: 2059

What does it mean when we use a variable like a Template in C++?

I am reading a C++ book. I encountered a code similar to the following:

int foo=3;
if(foo<1>(3))
    cout<<"hello world!"<<endl;

So, how is the int foo being used as a template? What does it mean?

I BELIEVE : This is a huge ambiguity of C++ because If we have a template code like this, what will happen?? How does C++ handle this ambiguity?

template <int N>
  void foo( const int t )
  {
     // ....
  }

Upvotes: 1

Views: 87

Answers (1)

Mooing Duck
Mooing Duck

Reputation: 66952

This is absolutely bizarre code, so if the book doesn't explain it, burn the book and demand a refund. The summary is: it's not a template. It's a less than comparison, and a greater than comparison.

if(foo<1>(3))

Is identical to

if( (foo<1) >3)

Which is nearly identical to

bool first = (foo < 1);  //false since `foo` is 3
bool second = (first > 3); //false evaluates to zero, so this is false as well
if (second) //this is never entered
    cout<<"hello world!"<<endl; //compiler probably doesn't even generate this.


As for your question about template ambiguities, the language clearly specifies somewhere what the default is, though it often isn't the one you want. I compiled your sample and found that it emits this: warning: comparisons like 'X<=Y<=Z' do not have their mathematical meaning [-Wparentheses] http://coliru.stacked-crooked.com/a/49479996464507dc. So we know it's still being interpreted as operators and ignoring the templates for this case.

But yes, there are many places where C++ is "ambiguous" in these ways. The most common is the "most vexing parse".

struct A {};
struct B {
    B(A a) {}
};
int main() {
    B obj(A());

You'd expect this to create an B named obj using a default-constructed A, but instead it declares a function named obj that returns a B and it's parameter is itself a function that takes nothing and returns an A. Then when you attempt to use it as a variable, you get all sorts of strange and confusing errors: http://coliru.stacked-crooked.com/a/c6fd627be8529b26

A much more insidious version is this:

template <class T>
struct A {
    static int v;
};
template<>
struct A<int>
    using v = float;
};
template<class T>
struct B {
    B() {
        A<T>::v;
    }
};

Inside B, it's hard if not impossible to tell if v is a type or a variable. This one was so bad that C++ had to add a special keyword typename so that programmers could tell the compiler that it was actually a type, because the compiler would always assume it was a variable.

Upvotes: 10

Related Questions