0

I was studying Algorithm in C++ using CLion.
I'm currently using Windows 10, Clion 2021.3.3 with bundled MingW
I was working on code, Merge Sort algorithm, and I had chance to use vector.emplace_back().
Whenever I try to use vector.emplace_back() my CLion complier tries to make my code like this.

v.template emplace_back();

I know that Clion is based on Clang-tidy which tries to make my code better and prettier,
but how come this code works?
I had no problem or error when I was compiling my code in Clion.
I know that most of us simply just use vector.emplace_back() or vector.push_back(), and it works well in any other IDEs.
I tried to run above usage in both Visual Studio 2022 (C++ 20) and repl.it. In repl.it, it worked and Visual Studio returned me C2059 syntax error : 'template'.
So I looked up cppreference.com and cplusplus.com to figure out this usage, and neither of them mentioned about this kind of usage.
I do understand that there are some differences between IDEs but it would be great someone who can answer how does my code works.
Below code is my Merge Sort code.

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;

template<typename T>
vector<T> merge(vector<T>& arr1, vector<T>& arr2) {
    vector<T> merged;

    auto iter1 = arr1.begin();
    auto iter2 = arr2.begin();

    while(iter1 != arr1.end() && iter2 != arr2.end()) {
        if (*iter1 < *iter2) {
            merged.template emplace_back(*iter1);
            iter1++;
        }
        else {
            merged.template emplace_back(*iter2);
            iter2++;
        }
    }
    if (iter1 != arr1.end()) {
        for (; iter1 != arr1.end(); iter1++)
            merged.template emplace_back(*iter1);
    }
    else {
        for (; iter2 != arr2.end(); iter2++)
            merged.template emplace_back(*iter2);
    }
    return merged;
}

template<typename T>
vector<T> merge_sort(vector<T> arr) {
    if (arr.size() > 1) {
        auto mid = size_t(arr.size() / 2);
        auto left = merge_sort<T>(vector<T>(arr.begin(), arr.begin() + mid));
        auto right = merge_sort<T>(vector<T>(arr.begin() + mid, arr.end()));
        return merge<T>(left, right);
    }
    return arr;
}

Here is my CMakeList.txt which is nothing special.

cmake_minimum_required(VERSION 3.21)
project(Data)

set(CMAKE_CXX_STANDARD 20)

add_executable(Data main.cpp)

To wrap it up, it would be grateful if someone can tell how does my code works fine, and where should I refer to to to solve my question?

merged.template emplace_back(*iter1);


Respectfully,
Minjae Lee
  • 31
  • 6
  • 4
    `template` is not required there. [where-and-why-do-i-have-to-put-the-template-and-typename-keywords](https://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords) might interest you. – Jarod42 Feb 15 '22 at 10:24
  • 2
    This seems like a bug in the tool recommending that change. There's no need to disambiguate this for the parser unless you have explicit `<>` in there. – chris Feb 15 '22 at 10:27
  • 1
    Please also read ["Why should I not #include ?"](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h") and ["Why is "using namespace std;" considered bad practice?"](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice"). You should also think carefully about the possible impact of `#define endl '\n'` . – G.M. Feb 15 '22 at 10:30

1 Answers1

2

I don't know what is wrong with your clang-tidy setup in CLion, but I cannot reproduce the message.

In any case, the message is wrong. The keyword template may be prefixed before a name only if the name is a template-id (except in one case that doesn't matter here), so v.template emplace_back<>(); would be allowed, but v.template emplace_back(); isn't. Some compilers are quite lax of enforcing this rule, so they will accept the version with template prefix as well, but technically that is wrong.

If for some reason you used a template argument list as in merged.template emplace_back<>();, for which there is absolutely no reason on emplace_back, then you would indeed need to add the template prefix, because the type of merged in your code is dependent on the template parameter T and so template is needed to disambiguate the < in the template argument list from being a less-than operator without needing to instantiate the template.

user17732522
  • 53,019
  • 2
  • 56
  • 105
  • Feel like reinstalling Clion would be better option for me since I hadn't manipulated any option in my Clion. Thanks for your answer by the way. – Minjae Lee Feb 16 '22 at 08:13