能否用用户定义推导指南解决嵌套名称说明符的非推导上下文问题?
能否用用户定义推导指南解决嵌套类型的模板参数推导问题?
这段代码无法直接运行,原因是nested-name-specifier会形成非推导上下文,导致foo(i)无法自动推导模板参数T。我尝试过多种用户定义推导指南,但都没能解决问题,想知道这种方案到底可行吗?
代码示例
template <class T> struct Outer final { struct Inner { Inner(Outer<T> o){}; }; }; template <class T> using OuterInner = Outer<T>::Inner; template <typename T> T foo(OuterInner<T> & engine) { return T(); } int main() { Outer<int> o; OuterInner<int> i(o); // 可行:foo<int>(i); return foo(i); // 无法编译 }
结论:用户定义推导指南无法解决这个问题
推导指南的作用范围是类模板的对象推导,而这里的核心问题出在函数模板foo的参数推导阶段。OuterInner<T>本质是Outer<T>::Inner的别名,在函数参数中,嵌套于类模板内部的类型(即Outer<T>::Inner)属于C++标准规定的非推导上下文——编译器没办法从实参i的具体类型反推出模板参数T,推导指南根本触及不到这个环节的推导逻辑。
可行的替代方案
方案1:显式指定模板参数
直接用代码中注释的写法foo<int>(i),手动明确T的类型,这是最直接的解决方式。方案2:给
Inner添加类型成员辅助推导
修改Outer的定义,让Inner暴露对应的T类型:template <class T> struct Outer final { struct Inner { using value_type = T; // 添加类型成员 Inner(Outer<T> o){}; }; };然后调整
foo的模板定义,从传入的Inner类型中提取value_type:template <typename InnerType> typename InnerType::value_type foo(InnerType& engine) { return typename InnerType::value_type(); }这样
foo(i)就能正常编译,编译器会自动从InnerType(即Outer<int>::Inner)中获取value_type作为返回类型。方案3:替换别名模板为类模板(不推荐)
把OuterInner改成类模板而非别名模板,再为其添加推导指南,但这种方式只是绕开了原问题,代码复杂度更高,不如方案2简洁。
内容的提问来源于stack exchange,提问作者hr0m
相关产品推荐
相关产品推荐

