嵌套模板类中静态函数相关代码能否通过C++14编译?
Great question! Let's break this down clearly, starting with a concrete example matching your description (since you didn't share the exact code, I'll assume the correct form first):
#include <type_traits> template <typename T> struct Outer { template <typename U> struct Inner { static void foo() {} }; }; template <typename T, typename U> auto get_foo_ptr() { // Critical: Use `template` here because Outer<T> is a dependent type return std::integral_constant< decltype(&Outer<T>::template Inner<U>::foo), &Outer<T>::template Inner<U>::foo >{}; } int main() { auto ptr = get_foo_ptr<int, char>(); }
Short Answer
If your code uses the template keyword as shown above to access the nested Inner template, it should absolutely compile under C++14, and the GCC 7.3 error is a compiler bug. Clang 6.0.0's behavior here is correct and standards-compliant.
If you omitted the template keyword (writing &Outer<T>::Inner<U>::foo instead), then your code is technically invalid under the standard, and Clang's successful compilation is due to a non-standard extension.
Detailed Explanation
Let's unpack the rules at play:
1. Dependent Names and the template Keyword
When working with nested templates inside a dependent type (like Outer<T>, where T is a template parameter), the C++ standard requires you to use the template keyword to explicitly mark Inner as a template. Without it, the compiler can't tell if Inner is a member variable (and Inner<U> is a comparison expression) or a template. This is defined in the C++14 standard's [temp.dep]/3 section.
If you included this template keyword, your code is syntactically valid. GCC 7.3 fails here because of a known implementation bug in how it resolves member pointers to nested templates within decltype expressions—this was fixed in later GCC versions (starting around GCC 8).
2. std::integral_constant and Function Pointers
std::integral_constant is designed to wrap compile-time constants, including function pointers. The type argument (decltype(&Outer<T>::template Inner<U>::foo)) correctly resolves to the function pointer type void (*)(), and the value argument is a valid compile-time constant (the address of the static function foo). This usage is fully compliant with C++14.
3. Auto Return Type Deduction
C++14 allows auto as a function return type, where the compiler deduces the type from the return statement. Here, the return expression is an instance of std::integral_constant<void (*)(), &Outer<T>::template Inner<U>::foo>, which the compiler can correctly deduce as the return type—this is a standard feature.
What to Do Next?
- If you already used the
templatekeyword: Upgrade your GCC version to 8 or later, and the error should disappear. - If you omitted the
templatekeyword: Add it to make your code standards-compliant (this will also fix the GCC error while keeping Clang compatibility).
内容的提问来源于stack exchange,提问作者DarthRubik

