I want to write code like this in vim (vim 9.0)

#include <iostream>
#include <string>

template <class T1, class T2>
concept composable = requires(T1 lhs, T2 rhs) { lhs + rhs; };

template <class T1, class T2>
requires composable<T1, T2>
constexpr auto compose(T1 lhs, T2 rhs) -> decltype(lhs + rhs)
    return lhs + rhs;

auto main() -> int
    using std::cout, std::endl, std::string;
    cout << compose(5, 8) << endl;
    cout << compose(5, 8.4) << endl;
    cout << compose(string("Hello "), string("world!")) << endl;

    return 0;

However when I do, I get lots of error messages by the language server, like

compose.cpp|6 col 1 error| unknown type name 'concept' [clang-diagnostic-error]
compose.cpp|6 col 31 error| 'T1' does not refer to a value [clang-diagnostic-error]
compose.cpp|6 col 39 error| 'T2' does not refer to a value [clang-diagnostic-error]
compose.cpp|11 col 1 error| unknown type name 'requires' [clang-diagnostic-error]
compose.cpp|11 col 10 error| variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list [clang-diagnostic-error]
compose.cpp|12 col 14 error| expected ';' at end of declaration [clang-diagnostic-error]
compose.cpp|13 col 24 error| unknown type name 'T1' [clang-diagnostic-error]
compose.cpp|13 col 32 error| unknown type name 'T2' [clang-diagnostic-error]

Which suggests that c++20 is not being used. However when I compile that code, it works flawlessly with both g++ and clang++ with no errors whatsoever.

I use dense-analysis/ale. I have read in numerous places, like this post, including the clangd documentation, that I should either create a file in ~/.config/clangd/config.yaml for a global user configuration, or a ./.clangd file for a project configuration.

I have done both, but neither seems to have any effect whatsoever.

First I created the user configuration, because I don't like littering my project with random config files and like to be consistent between my projects anyway. That file is in /home/user/.config/clangd/config.yaml and looks like so:

  Add: [-std=c++20, -Wall, -Wextra, -Wpedantic, -Wdouble-promotion, -Wformat=2, -Wformat-nonliteral, -Wformat-y2k, -Wnull-dereference, -Wimplicit-fallthrough, -Wmissing-include-dirs, -Wswitch-default, -Wunused-parameter, -Wuninitialized, -Wsuggest-attribute=const, -Walloc-zero, -Walloca, -Wconversion, -Wfloat-conversion, -Wsign-conversion, -Wduplicated-branches, -Wduplicated-cond, -Wtrampolines, -Wfloat-equal, -Wshadow=compatible-local, -Wundef, -Wunused-macros, -Wcast-qual, -Wcast-align=strict, -Wlogical-op, -Wmissing-declarations, -Wredundant-decls, -Wstack-protector, -fstack-protector, -pedantic-errors, -Werror=pedantic, -Werror=char-subscripts, -Werror=null-dereference, -Werror=init-self, -Werror=implicit-fallthrough=2, -Werror=misleading-indentation, -Werror=missing-braces, -Werror=multistatement-macros, -Werror=sequence-point, -Werror=return-type, -Werror=multichar,-Wno-unknown-warning-option]

That had no effect on the error messages being displayed in vim. So I created the .clangd file in my project. The contents are


This also didn't work at all. What am I doing wrong? How do I get to write code with c++20 features and not get false errors?

I also tried

  Add: [-std=c++20]

with the same results.

I also tried setting

let g:ale_cpp_cc_options = '-std=c++20 -fstack-protector -Wall -Wextra -Wpedantic -Wdouble-promotion -Wformat=2 -Wformat-nonliteral -Wformat-signedness -Wformat-y2k -Wnull-dereference -Wimplicit-fallthrough=2 -Wmissing-include-dirs -Wswitch-default -Wunused-parameter -Wuninitialized -Wsuggest-attribute=const -Walloc-zero -Walloca -Wconversion -Wfloat-conversion -Wsign-conversion -Wduplicated-branches -Wduplicated-cond -Wtrampolines -Wfloat-equal -Wshadow=compatible-local -Wundef -Wunused-macros -Wcast-qual -Wcast-align=strict -Wlogical-op -Wmissing-declarations -Wredundant-decls -Wstack-protector -pedantic-errors -Werror=pedantic -Werror=char-subscripts -Werror=null-dereference -Werror=init-self -Werror=implicit-fallthrough=2 -Werror=misleading-indentation -Werror=missing-braces -Werror=multistatement-macros -Werror=sequence-point -Werror=return-type -Werror=multichar -Wno-unknown-warning-option'

in my .vimrc, which also didn't get rid of the false errors.

Clang and clang tools, including clangd and clang-tidy versions are Ubuntu clang version 17.0.0 (++20230623042322+7175d6a5966a-1~exp1~20230623042442.1015), but again, actually compiling the source code with g++ and clang yields no errors or warnings, as long as I specify -std=c++20.

I switched to coc and that works just fine.


1 Answer 1


I am also using Vim 9.0 with ALE plugin

I am also configuring ALE for different programming languages. I saw your post and decided to try C++ first. Thank you for posting this query.

I tried your code, ALE worked as expected. I only used .vimrc file to define everything (no other files)

" Lint .h files as C++, not C
let g:ale_pattern_options_enabled = 1
let g:ale_pattern_options = { '\.h$': { 'ale_linters': { 'cpp' : ['cc', 'gcc', 'clang'] } } }

" Set flags for gcc/clang
let cpp_opts = '-std=c++20 -Wall -Wextra'
let g:ale_linters = { 'cpp': ['cc', 'gcc', 'clang'] }
let g:ale_cpp_cc_options    = cpp_opts
let g:ale_cpp_gcc_options   = cpp_opts
let g:ale_cpp_clang_options = cpp_opts

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.