2

I was compiling the following code and GCC seems to accept the following code.

#include <map>

template<typename K, typename V>
class my_map {
private:
    std::map<K, V> mmap;
public:
    typedef std::map<K, V>::iterator iterator;
    typedef std::map<K, V>::const_iterator const_iterator;

    iterator begin() {return mmap.begin();}
    const_iterator begin() const {return mmap.begin();}

};

int main()
{
    my_map<int, int>::iterator whatever;
    return 0;
}

But clang complains about the missing typename keyword. The complaint of clang makes more sense to me. Is this a GCC bug?

Edit: Obviously, Where and why do I have to put the "template" and "typename" keywords? does not answer my question, as I am not asking what typename keyword is, but asking about different behaviors of compilers.

Edit: Now the program is accepted by both clang(from version 16) and gcc.

Karen Baghdasaryan
  • 2,407
  • 6
  • 24
  • 1
    IIRC this stuff is dependent on the version of C++ you are compiling for. Which version are you using? – john Jul 15 '22 at 12:04
  • I can't remember what version relaxes these rules (pretty sure it is C++20) but I know for sure that in C++17 and older you need the typename. If you want your code to be backwards compatible I would keep the `typename` – NathanOliver Jul 15 '22 at 12:04
  • I am using C++20 – Karen Baghdasaryan Jul 15 '22 at 12:05
  • More likely to be a g++ *extension* than a bug. – Adrian Mole Jul 15 '22 at 12:05
  • @AdrianMole Then I would suppose that clang should behave similarly. – Karen Baghdasaryan Jul 15 '22 at 12:06
  • 5
    Can confirm, clang bug as it is a C++20 feature: https://stackoverflow.com/questions/61990971/why-dont-i-need-to-specify-typename-before-a-dependent-type-in-c20 – NathanOliver Jul 15 '22 at 12:07
  • *Then I would suppose that clang should behave similarly.* Why would you suppose that? They are different compilers, being maintained by different people, who are at different places in supporting C++20. Supporting C++20 is still a work-in-progress for Clang, GCC, VS's CL.EXE, and most/all other C++ vendors. – Eljay Jul 15 '22 at 12:08
  • 1
    MSVC accepts the code without `typename` if using C++20 (but not with C++17). @NathanOliver – Adrian Mole Jul 15 '22 at 12:09
  • @Elijay In case the behavior is defined by the standard, shouldn't we expect that it should be implemented accordingly in both compilers? – Karen Baghdasaryan Jul 15 '22 at 12:10
  • 2
    @AdrianMole Woot. For once it's not MSVC getting it wrong ;) – NathanOliver Jul 15 '22 at 12:11
  • 2
    @NathanOliver I would call this unimplemented feature not a bug, since support for C++20 is still under development. [Here](https://en.cppreference.com/w/cpp/compiler_support/20#C.2B.2B14_library_features) this feature is marked as unimplemented by clang yet. – Marek R Jul 15 '22 at 12:16
  • 3
    But it's 2022, already. :( – Adrian Mole Jul 15 '22 at 12:27
  • @KarenBaghdasaryan Oh, i see :) – Jason Nov 04 '22 at 11:44

1 Answers1

2

asking about different behaviors of compilers.

It seems that Clang has not implemented this C++20 feature yet. This can be seen from compiler support documentation. This means clang is not standard compliant.

C++20 feature Paper(s) GCC Clang MSVC Apple Clang
Allow lambda-capture [=, this] P0409R2 8 6 19.22* 10.0.0*
Make typename more optional P0634R3 9 19.29 (16.10)*
Pack expansion in lambda init-capture P0780R2 9 9 19.22* 11.0.3*

As we can see in the above above table, the entry for clang corresponding to "Make typename more optional" is blank.

On the other hand GCC and MSVC have implemented this C++20 feature and so are standard compliant. GCC and MSVC Demo


Update

As of 03/11/2022, clang supports this with version 16 as shown in the updated table below:

C++20 feature Paper(s) GCC Clang MSVC Apple Clang
Allow lambda-capture [=, this] P0409R2 8 6 19.22* 10.0.0*
Make typename more optional P0634R3 9 16 19.29 (16.10)*
Pack expansion in lambda init-capture P0780R2 9 9 19.22* 11.0.3*

The program compiles with clang trunk.

Jason
  • 36,170
  • 5
  • 26
  • 60