为何Eclipse对该C++模板代码报「无效模板参数」错误?
我有一段C17代码,改编自codereview上的《C17: Boost.Hana based compile-time plugin registration》示例,已合并为单文件并移除Boost相关内容:
#include <iostream> #include <type_traits> template<class> struct sfinae_true; template<unsigned int> struct registry_hook; namespace registry { template<class Dummy, unsigned int testN> constexpr sfinae_true<decltype(registry_hook<testN>{})> test(int); template<class Dummy, unsigned int testN> constexpr std::false_type test(long); template<class Dummy, unsigned int testN = 0> constexpr unsigned int get_free_N() { if constexpr (std::is_same<decltype(test<Dummy, testN>(0)), std::false_type>::value) { return testN; } else { return get_free_N<Dummy, testN + 1>(); } } } struct Dummy1; template<> struct registry_hook<registry::get_free_N<Dummy1>()> { constexpr static unsigned int my_N = registry::get_free_N<Dummy1>(); }; struct Dummy2; template<> struct registry_hook<registry::get_free_N<Dummy2>()> { constexpr static unsigned int my_N = registry::get_free_N<Dummy2>(); }; int main() { constexpr unsigned int max_N = registry::get_free_N<void>() - 1; std::cout << max_N << std::endl; }
这段代码在GCC和Clang下均可正常编译运行:
$ g++ -std=c++17 -Wall -Wextra -pedantic main.cc && ./a.out 1 $ clang++ -std=c++17 -Wall -Wextra -pedantic main.cc && ./a.out 1
但Eclipse(CDT)对其中的显式模板特化代码提示Invalid template argument错误,解析日志仅显示如下内容:
Project: test
File: file:[…]/main.cc
Language: GNU C++
Index Version: 220.0
Build Configuration: Default
Context: file:[…]/main.cc
C++, {}
Versions in Index: 1
C++: {}; 0 macros, 2 includes, 47 names;Include Search Path (option -I):
/usr/include/c++/11
/usr/include/x86_64-linux-gnu/c++/11
/usr/include/c++/11/backward
/usr/lib/gcc/x86_64-linux-gnu/11/include
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/includeMacro definitions (option -D):
[…]Unresolved names:
A template id provides illegal arguments for the instantiation: registry_hook in file […]/main.cc:28
A template id provides illegal arguments for the instantiation: registry_hook in file […]/main.cc:34Written on Tue Dec 05 23:01:27 EST 2023
这段代码完全符合C++17标准,主流编译器均能正确处理,因此这是Eclipse CDT的静态分析器bug——它无法正确解析依赖SFINAE机制的编译期常量表达式作为模板特化参数的场景。
内容的提问来源于stack exchange,提问作者Socob

