অপারেটর << অবশ্যই একটি যুক্তি নিতে হবে


94

আহ

#include "logic.h"
...

class A
{
friend ostream& operator<<(ostream&, A&);
...
};

logic.cpp

#include "a.h"
...
ostream& logic::operator<<(ostream& os, A& a)
{
...
}
...

আমি যখন সংকলন করি তখন তা বলে:

std :: ostream & যুক্তি :: অপারেটর << (std :: ostream &, A &) 'অবশ্যই এক যুক্তি নিতে হবে।

সমস্যাটা কি?

উত্তর:


132

সমস্যাটি হল আপনি ক্লাসের ভিতরে এটি সংজ্ঞায়িত করেন যা

ক) এর অর্থ দ্বিতীয় যুক্তিটি অন্তর্নিহিত ( this) এবং

খ) এটি আপনি যা করতে চান তা করবে না, নাম বাড়িয়ে দেবে std::ostream

আপনাকে এটিকে একটি ফ্রি ফাংশন হিসাবে সংজ্ঞায়িত করতে হবে:

class A { /* ... */ };
std::ostream& operator<<(std::ostream&, const A& a);

9
এছাড়াও, তিনি এটিকে ফ্রেন্ড ফাংশন হিসাবে ঘোষণা করেন এবং এটিকে সদস্য ফাংশন হিসাবে সংজ্ঞায়িত করেন।
asaelr

যেমন en.cppreferences.com/w/cpp/language/operators এ উল্লিখিত হয়েছে , "অপারেটর >> এবং অপারেটরের ওভারলোডস << যে একটি std :: istream & বা std :: ostream নেয় এবং বাম হাতের যুক্তি সন্নিবেশ হিসাবে পরিচিত এবং নিষ্কাশন অপারেটরগুলি: যেহেতু তারা ব্যবহারকারী-সংজ্ঞায়িত প্রকারটিকে সঠিক আর্গুমেন্ট হিসাবে গ্রহণ করে (একটি @ বিতে বি), তাদের অবশ্যই সদস্যবিহীন হিসাবে প্রয়োগ করা হবে "।
মোর্তেজা

49

একটি বন্ধু ফাংশন সদস্য ফাংশন নয়, সুতরাং সমস্যাটি হ'ল আপনি তার operator<<বন্ধু হিসাবে ঘোষণা করেছেন A:

 friend ostream& operator<<(ostream&, A&);

তারপরে ক্লাসের সদস্য ফাংশন হিসাবে এটি সংজ্ঞায়িত করার চেষ্টা করুন logic

 ostream& logic::operator<<(ostream& os, A& a)
          ^^^^^^^

logicকোনও শ্রেণি বা নাম স্থান কিনা তা নিয়ে আপনি কি বিভ্রান্ত ?

ত্রুটিটি কারণ আপনি কোনও সদস্যকে operator<<দুটি টি যুক্তি নিয়ে সংজ্ঞা দেওয়ার চেষ্টা করেছেন যার অর্থ এটি অন্তর্ভুক্ত thisপরামিতি সহ তিনটি যুক্তি লাগে ments অপারেটর কেবল দুটি আর্গুমেন্ট নিতে পারে, যাতে আপনি a << bদুটি আর্গুমেন্ট লেখার সময় aএবং হয় b

আপনি ostream& operator<<(ostream&, const A&)একটি অ- সদস্য ফাংশন হিসাবে সংজ্ঞায়িত করতে চান , অবশ্যই কোনও সদস্য হিসাবে নয় কারণ এর logicসাথে এই শ্রেণীর কোনও সম্পর্ক নেই!

std::ostream& operator<<(std::ostream& os, const A& a)
{
  return os << a.number;
}

3

টেম্পলেটেড ক্লাস নিয়ে আমি এই সমস্যায় পড়েছি। এখানে আমাকে আরও সাধারণ সমাধান ব্যবহার করতে হয়েছিল:

template class <T>
class myClass
{
    int myField;

    // Helper function accessing my fields
    void toString(std::ostream&) const;

    // Friend means operator<< can use private variables
    // It needs to be declared as a template, but T is taken
    template <class U>
    friend std::ostream& operator<<(std::ostream&, const myClass<U> &);
}

// Operator is a non-member and global, so it's not myClass<U>::operator<<()
// Because of how C++ implements templates the function must be
// fully declared in the header for the linker to resolve it :(
template <class U>
std::ostream& operator<<(std::ostream& os, const myClass<U> & obj)
{
  obj.toString(os);
  return os;
}

এখন: * আমার টুস্ট্রিং () ফাংশনটি ইনপলিন হতে পারে যদি এটি সিপিতে টিক করা যায়। * আপনি হেডারে কিছু কোড দিয়ে আটকে গেছেন, আমি এ থেকে মুক্তি পেতে পারি না। * অপারেটর টসস্ট্রিং () পদ্ধতিতে কল করবে, এটি কোনও ইনলাইনড নয়।

অপারেটরের বডি << ফ্রেন্ড ক্লোজে বা ক্লাসের বাইরে ঘোষণা করা যেতে পারে। উভয় বিকল্প কুরুচিপূর্ণ। :(

হতে পারে আমি ভুল বোঝাবুঝি করছি বা কিছু মিস করছি তবে কেবল অপারেটর টেম্পলেটটি জিসিসিতে লিঙ্ক করে না।

এটিও কাজ করে:

template class <T>
class myClass
{
    int myField;

    // Helper function accessing my fields
    void toString(std::ostream&) const;

    // For some reason this requires using T, and not U as above
    friend std::ostream& operator<<(std::ostream&, const myClass<T> &)
    {
        obj.toString(os);
        return os;
    }
}

আমি মনে করি আপনি হেডারগুলিতে জোর করে ঘোষণামূলক সমস্যাগুলি এড়াতেও পারেন, যদি আপনি এমন কোনও অভিভাবক শ্রেণি ব্যবহার করেন যা অপারেটর << প্রয়োগ করার জন্য টেম্পলড হয় না এবং ভার্চুয়াল টুস্ট্রিং () পদ্ধতি ব্যবহার করে।


0

আপনি যদি operator<<সদস্য ফাংশন হিসাবে সংজ্ঞায়িত হন তবে এটিতে আপনি কোনও সদস্যবিহীন ব্যবহার করেছেন তার চেয়ে আলাদা পচানো বাক্য গঠন থাকবে operator<<। একটি অ-সদস্য operator<<হ'ল একটি বাইনারি অপারেটর, যেখানে সদস্যটি operator<<অ্যানারি অপারেটর।

// Declarations
struct MyObj;
std::ostream& operator<<(std::ostream& os, const MyObj& myObj);

struct MyObj
{
    // This is a member unary-operator, hence one argument
    MyObj& operator<<(std::ostream& os) { os << *this; return *this; }

    int value = 8;
};

// This is a non-member binary-operator, 2 arguments
std::ostream& operator<<(std::ostream& os, const MyObj& myObj)
{
    return os << myObj.value;
}

সুতরাং .... আপনি কীভাবে তাদের কল করবেন? অপারেটররা কিছু উপায়ে অদ্ভুত, আমি আপনাকে চ্যালেঞ্জ operator<<(...)জানাব যাতে জিনিসগুলি বোধগম্য করতে আপনার মাথায় সিনট্যাক্স লিখবেন ।

MyObj mo;

// Calling the unary operator
mo << std::cout;

// which decomposes to...
mo.operator<<(std::cout);

অথবা আপনি সদস্যবিহীন বাইনারি অপারেটরকে কল করার চেষ্টা করতে পারেন:

MyObj mo;

// Calling the binary operator
std::cout << mo;

// which decomposes to...
operator<<(std::cout, mo);

এই অপারেটরগুলিকে সদস্য ফাংশনে পরিণত করার সময় স্বজ্ঞাতভাবে আচরণ করার আপনার কোনও বাধ্যবাধকতা নেই, আপনি চাইলে operator<<(int)বাম শিফ্টের কিছু সদস্য পরিবর্তনশীলকে সংজ্ঞায়িত করতে পারেন, বুঝতে পারেন লোকেরা কিছুটা রক্ষী হতে পারে, আপনি যত মন্তব্যই করুক না কেন লিখুন।

প্রায় শেষ পর্যন্ত, অনেক সময় অপারেটর কলের জন্য উভয় পচন বৈধ হয়ে থাকতে পারে, আপনি এখানে সমস্যার মধ্যে পড়তে পারেন এবং আমরা সেই কথোপকথনটি পিছিয়ে দেব।

অবশেষে, খেয়াল করুন যে বাইনারি অপারেটরের মতো দেখতে এমন একটি অ্যানারি সদস্য অপারেটর লেখার পক্ষে কতটা অদ্ভুত বিষয় হতে পারে (যেমন আপনি সদস্য অপারেটরগুলিকে ভার্চুয়াল করতে পারেন ..... এছাড়াও এই পথটি বিভ্রান্ত না করে চালানোর চেষ্টা করছেন .... )

struct MyObj
{
    // Note that we now return the ostream
    std::ostream& operator<<(std::ostream& os) { os << *this; return os; }

    int value = 8;
};

এই বাক্য গঠনটি এখন অনেক কোডারকে বিরক্ত করবে ...

MyObj mo;

mo << std::cout << "Words words words";

// this decomposes to...
mo.operator<<(std::cout) << "Words words words";

// ... or even further ...
operator<<(mo.operator<<(std::cout), "Words words words");

coutএখানে চেইনে দ্বিতীয় যুক্তিটি কীভাবে তা খেয়াল করুন .... বিজোড় ঠিক আছে?

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.