невозможно получить доступ к функции друга в классе шаблона - PullRequest
0 голосов
/ 23 ноября 2018

Класс Pairwise представляет пару с ключом: значением.Я создал пару шаблонов, и у меня возникли ошибки при попытке ввести ключ и значение в класс и распечатать его.

Учитывая мой основной:

#include "file_name.h"

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

И мой заголовокfile:

#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;
    }
};

Мой ожидаемый результат после запуска main будет:

key:value

Однако я получаю ошибку:

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

Ответы [ 3 ]

0 голосов
/ 23 ноября 2018

ч: 25: 59: объявление друга отменяет не шаблонную функцию.

Вы не можете объявить функцию как шаблон, который принимает 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';
}

Sidenote: Вы также можете использовать

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

, если вам это нужно чаще.

Другие ошибки, которые вы получили в результате смешения std::ostringstream с std::ostream в operator<<().

0 голосов
/ 23 ноября 2018

В 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

0 голосов
/ 23 ноября 2018

Когда вы пишете, вы определяете оператор как функцию-член, которая, скорее всего, не предназначена.Разделите это как ...

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 все члены по умолчанию являются открытыми;так что вы сможете получить к ним доступ даже при отсутствии объявления friend.

...