https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113242
Bug ID: 113242 Summary: g++ rejects-valid template argument of class type containing an lvalue reference Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: janschultke at googlemail dot com Target Milestone: --- ## Code to Reproduce struct wrapper { int& ref; constexpr wrapper(int& ref) : ref(ref) {} }; template <const wrapper& X> void fun1() {} template <wrapper X> void fun2() { fun1<X>(); } int main() { static int val = 22; fun2<val>(); } ## Incorrect Output (GCC 14, -std=c++20) (https://godbolt.org/z/1jzqza73z) <source>: In instantiation of 'void fun2() [with wrapper X = wrapper{val}]': <source>:16:14: required from here 16 | fun2<val>(); | ~~~~~~~~~^~ <source>:11:12: error: no matching function for call to 'fun1<wrapper{val}>()' 11 | fun1<X>(); | ~~~~~~~^~ <source>:7:6: note: candidate: 'template<const wrapper& X> void fun1()' 7 | void fun1() {} | ^~~~ <source>:7:6: note: template argument deduction/substitution failed: <source>:11:12: error: the address of 'wrapper{val}' is not a valid template argument 11 | fun1<X>(); | ~~~~~~~^~ ## Explanation None. Clang compiles this, but GCC doesn't. The reference contained within wrapper is a valid template argument (see https://eel.is/c++draft/temp.arg.nontype#6), but falsely disqualifies X in fun1 from binding to X in fun2. See https://stackoverflow.com/a/77764351/5740428 for a more detailed explanation for the relevant standardese.