我在处理简单参数相关查找/模板类型推断问题时遇到问题

I am having trouble with a simple argument dependent lookup / template type inferencing issue

我有这段代码,但我不明白为什么 std::cout 行没有编译...参数查找/模板参数推断似乎是正确的...

#include <iostream>

template<typename T>
struct A
{
    struct M1
    {
        T x;
    };
};

template<typename T>
std::ostream &operator<<(std::ostream &os, typename A<T>::M1 const &o)
{
    os << o.x;
    return os;
}


int main()
{
    A<int>::M1 a;

    std::cout << a; // This line fails

    return 0;
}

顺便说一句,我正在尝试在不将 operator<<() 声明为内联函数的情况下执行此操作。

您的问题是 T 处于非推导上下文中。 C++ 只会进行简单的模式匹配,它不会反转可能的任意类型映射。

想象一下 A<void> 的特化设置 using M1=A<int>::M1。现在 intvoid 都对您的 << 有效 T。由于这个问题通常很难解决,C++ 甚至拒绝尝试:​​您只能对参数类型的直接模板参数进行模式匹配。

做你真正想做的事:

template<typename T>
struct A {
  struct M1 {
    T x;
    friend std::ostream& operator<<(std::ostream& os, M1 const& m1){
      return os << m1.x;
    }
  };
};

学会爱上 Koenig 运算符。

无法推导出您的运算符的模板参数T。但是,使用一些 SFINAE 魔法有一些解决方法:

#include <iostream>

template<typename T>
struct A {
    struct M1 {
        using type = T;
        T x;
    };
};

template<typename T, std::enable_if_t<std::is_same<T, typename A<typename T::type>::M1>::value, int> = 0>
std::ostream &operator<<(std::ostream &os, const T& o)
{
    os << o.x;
    return os;
}

int main()
{
    A<int>::M1 a;
    std::cout << a; // This line works
    return 0;
}