1

I've been trying to work with templates for a while now and the more I do the less I realise I understand. This latest problem feels like it has unearthed a rather fundamental misunderstanding on my part and I'm starting to think more than ever that, "Right, tomorrow I shouldn't write any code but instead find a library with a good CS section and just read everything they have on templates"! I wonder if in the mean time you can help me.

So, the following code,

template <typename T>    // or replace `typename` with `class`
struct Foo {
    struct Bar {};
    Foo(Bar) {}
};

Foo<float>::Bar x;
Foo<int> y (x);

doesn't compile since x is of type Foo<float>::Bar but to construct y we need a Foo<int>::Bar. That's fine, and expected, but now consider the following,

template <int I>
struct Foo {
    struct Bar {};
    Foo(Bar) {}
};

Foo<0>::Bar x;
Foo<1> y (x);

I was hoping/thinking (although, thankfully, not as yet relying on) that x would be of type Foo<0>::Bar and to construct y we would need a Foo<1>::Bar and as such it would not compile - as in the previous example. But it seems that both are in fact of type Foo<int>::Bar and so, this will compile.

So, I wonder, what, first, is the correct terminology to describe this difference between a typename/class parameterized template and an integral type parameterized one, what other differences in behaviour does this entail, and, what method could I use to solve this problem and get the desired behaviour for this simple example so that Foo<0> and Foo<1> will describe incompatible types?

And, before that trip to the library, any links to "essential", online, reading materials on the subject would be welcomed too. Thanks.

tjm
  • 7,500
  • 2
  • 32
  • 53
  • 2
    Your latter example doesn't compile on GCC. Which compiler are you using? – Yuji Jul 19 '10 at 21:50
  • 2
    The code you give certainly shouldn't compile, for exactly the reason you give: `Foo<0>` and `Foo<1>` are distinct types. Which compiler are you using? – Mike Seymour Jul 19 '10 at 21:50
  • And take this list to the library with you: http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – Mike Seymour Jul 19 '10 at 21:53
  • I apologise. I'm using GCC and you're absolutely right, the code I posted *doesn't* compile. My problem 1st appeared in a more convoluted example, but I really did think I'd tested the code I posted, it seems tho I spent too long composing the question and lost track of the most important part, the code example. I'm trying to recreate the simple example I did have which still failed, and will update the question when I have it. It's good to know that it wasn't what I thought it was though. & thankyou Mike for the reading list. I'll be sure to take it with me.Really sorry for wasting your time. – tjm Jul 19 '10 at 22:18
  • I think i've recreated the example and I think now, with the confidence that you guys have given me that the problem I posed here is not wrong, understand why it was failing. It wasn't related to templates. Thankyou for your help and once again sorry for taking your time. I will delete this question in a little while. I just want to leave this here for a moment to explain whats going on to those of you who replied. Thankyou. – tjm Jul 19 '10 at 22:41
  • Oh! I can't delete it. Well then, a final apology to anyone who comes by this and gets confused by it. Basically what I said is completely **wrong**. And an open invitation to any moderators who come by to feel free to delete it. – tjm Jul 19 '10 at 22:52
  • 2
    It shouldn't be deleted, it contains valid information. – GManNickG Jul 19 '10 at 23:14

1 Answers1

2

On gcc 4.4.3 your second example fails to compile with the message "error: no matching function for call to 'Foo<1>::Foo(Foo<0>::Bar&)'", which is exactly what you expected to happen.

So you did not misunderstand anything. If this compiles for you, that's non-standard behavior by your compiler.

sepp2k
  • 363,768
  • 54
  • 674
  • 675