2
template<int N>
struct foo {
        template<int M>
        void f(int i){}
};

template<int N>
void bar() {
        foo<N> m;
        m.f<1>(1);      // line A
}

int main(){
        bar<1>();
        foo<1> n;
        n.f<1>(1);      // line B
        return 0;
}

GCC sees < as the less-than operator in line A but not in line B.

Is there some kind of "relaxed-mode" in which GCC can handle line A as MSVC does, so that I don't have to write m.template f<1>(1)?

Museful
  • 6,711
  • 5
  • 42
  • 68
  • Why would you want that mode? Even if MSVC outright rejects the keyword, I’d sooner introduce a macro that expanded to `template` everywhere else. – Davis Herring May 27 '18 at 04:49
  • @DavisHerring MSVC doesn't reject the keyword. The standards-compliant way is to write `m.template f<1>(1)`. I just don't want to write that all over my code as I feel it reduces readability. Any trick that in general allows use of the simpler syntax at the call-site is fine as an answer. – Museful May 27 '18 at 08:32
  • What about readability for people who know the language and marvel at the implicit claim that you _do_ mean `(m.f<1)>1`? – Davis Herring May 27 '18 at 14:08
  • The only trick (besides `#define H template` and `#define tmethod template method`) I’ve ever seen for this works only if `bar` can be a method on a derived class (template). Is that of interest here? – Davis Herring May 27 '18 at 14:15
  • @DavisHerring IMO it's unreasonable of the standard to interpret lines A and B inconsistently – Museful May 27 '18 at 16:18
  • At line B, everything is known about `foo<1>`. At line A, it is possible that `foo` is (or will be) specialized such that `m.f` is not a template. The compiler must know whether it is (meant to be) one to parse the `<` correctly. It happens that being a type, or being a template, is never the default in case of ambiguity and must be marked with a keyword. – Davis Herring May 27 '18 at 17:54
  • @DavisHerring Would that mean MSVC goes to special additional trouble just to violate the standard on this point? – Museful May 27 '18 at 18:43
  • It’s more that MSVC doesn’t bother doing much validity checking on a template before instantiating it, so it doesn’t notice the error. You _can_ see that as a good thing in this case, but it of course causes headaches in other situations. – Davis Herring May 27 '18 at 19:33
  • Your options are (a) writing `m.template f<1>(1)` or (b) writing your own compiler for your own language. – n. m. could be an AI May 27 '18 at 20:30
  • @DavisHerring I'm very curious in what kind of situation MSVC would cause a headache. – Museful May 27 '18 at 22:58
  • @n.m. (b)? It seems easier to just use MSVC. – Museful May 27 '18 at 23:05
  • If you are OK with being confined to their OS, go ahead. – n. m. could be an AI May 28 '18 at 03:25
  • @Museful: Here's an [example](https://godbolt.org/g/svrxC6), where the programmer thought `A::B` was a _template_ type alias and left out the disambiguation keywords in `foo`. GCC's resulting error messages aren't great, but MSVC's is... special. – Davis Herring May 28 '18 at 05:00
  • @Museful, consider this: MS will (may) fix this particular non-conformance one day and you'll have to change the code even if you stay on MSVC. – Andrei R. May 28 '18 at 06:32

0 Answers0