在非推导的上下文中解决模板参数的方法

时间:2011-11-29 09:10:05

标签: c++ templates template-deduction

请考虑以下代码:

#include <iostream>

template<class T>
struct outer {
    struct inner {};
};

template<class T>
std::ostream& operator<<(std::ostream & stream, 
                         typename outer<T>::inner const& value) {
    std::cout << "An outer::inner!";
    return stream;
}

int main() {
    outer<float>::inner foo;

    std::cout << foo << std::endl; // does not compile
}

这不编译,因为typename outer<T>::inner非弱化上下文(如here所述),这意味着编译器无法推断出模板参数类型(读取) this answer为什么)。在我看来,我有两个选项可以让它发挥作用:

  1. inner移到outer之外,并将其设为类模板。我更喜欢这个,因为对使用代码的影响较小。
  2. 向内部添加to_string - 方法。
  3. 是否还有其他解决方案(在使用代码中不会导致语法难看)?

1 个答案:

答案 0 :(得分:22)

您可以将运算符移动到内部类主体中,并将​​friend放在其前面。然后只用inner替换参数类型。

另一种技术是从内部参数化的CRTP基础派生内部。然后使参数键入CRTP类并将参数引用强制转换为派生的inner类,其类型由您推导的模板参数给出。