无法访问模板中的好友功能 class

unable to access friend function in template class

Pairwise class 表示一对 key:value。我制作了一个模板对,但在尝试 运行 时遇到错误,将键和值输入到 class 并将其打印出来。

鉴于我的主要:

#include "file_name.h"

int main (){
    Pairwise<string, string> example = {{"key", "value"}};
    cout << example << endl;
 }

还有我的头文件:

#pragma once

#include<iostream>
using std::ostream; using std::cout; using std::endl;
#include<string>
using std::string;
#include<utility>
using std::pair;
#include<sstream>
using std::ostringstream;

template<typename K, typename V>
struct Pairwise{
    K first;
    V second;
    Pairwise() = default;
    Pairwise(K, V);
    //print out as a string in main
    friend ostream& operator<<(ostream &out, const Pairwise &n) {
        ostream oss;
        string s;
        oss << n.first + ":" + n.second; //possible error?
        s = oss.str();
        out << s; 
        return out;
    }
};

我在 运行ning main 之后的预期输出是:

key:value

但是,我收到错误消息:

h:28:11: error: 'std::basic_ostream<_CharT, _Traits> is protected within..."

在编写时,您将运算符定义为成员函数,这很可能不是故意的。把它分成...

template<typename K, typename V>
struct Pairwise{
    K first;
    V second;
    Pairwise() = default;
    Pairwise(K, V);
    //print out as a string in main
    friend ostream& operator<<(ostream &out, const Pairwise &n);
};

template<typename K, typename V>
ostream& operator<<(ostream &out, const Pairwise<K,V> &n) {
    ...
    return out;
}

它应该可以工作。

顺便说一句:请注意,在 struct 中,默认情况下所有成员都是 public;因此,即使没有 friend-声明,您也可以访问它们。

h:25:59: friend declaration delares a non template function.

您没有将函数声明为采用 Pairwise<K, V>:

的模板

header.h:

#ifndef HEADER_H_INCLUDED  /* or pragma once */
#define HEADER_H_INCLUDED  /* if you like it */

#include <iostream>  // or <ostream>

template<typename K, typename V>
class Pairwise {  // made it a class so that the
    K first;      // friend actually makes sense.
    V second;

public:
    Pairwise() = default;

    Pairwise(K first, V second)
    : first{ first }, second{ second }
    {}

    template<typename K, typename V>
    friend std::ostream& operator<<(std::ostream &out, Pairwise<K, V> const &p)
    {
        return out << p.first << ": " << p.second;
    }
};

#endif /* HEADER_H_INCLUDED */

源文件:

#include <iostream>  // the user can't know a random header includes it
#include <string>

#include "header.h"

int main()
{
    Pairwise<std::string, std::string> p{ "foo", "bar" };
    std::cout << p << '\n';
}

旁注:您也可以使用

{
    using Stringpair = Pairwise<std::string, std::string>;
    // ...
    Stringpair sp{ "foo", "bar" };
}

如果您更经常需要它。

您得到的其他错误是由于混淆了 std::ostringstreamoperator<<() 中的 std::ostream

在 C++ 中,少即是多...

#pragma once

#include<iostream>
#include<string>

// never do this in a header file:
// using std::ostream; 

template<typename K, typename V>
struct Pairwise{
    K first;
    V second;
    Pairwise() = default;
    Pairwise(K, V);
    //print out as a string in main
    friend std::ostream& operator<<(std::ostream &out, const Pairwise &n) {
        return out << n.first << ':' << n.second;
    }
};

int main (){
    using std::cout; using std::endl; using std::string;

    Pairwise<string, string> example = {"key", "value"};
    cout << example << endl;
 }

https://godbolt.org/z/ZUlLTu