গিসি তে দ্বিধাবিভক্ত অপারেটর


13

আমি স্টাইলের কিছু ধারক মুদ্রণের জন্য একটি ফাংশন টেম্পলেট তৈরি করেছি

#include <iostream>
#include <vector>
#include <string>

template <template <typename, typename> class C, typename T, typename A>
std::ostream& operator<<(std::ostream& os, const C<T, A>& container)
{ 
    for (auto& elem : container) 
    { 
        os << elem << " "; 
    } 

    return os; 
}

int main()
{
    std::vector<std::string> v { "One", "Two", "Three" };

    std::cout << v << std::endl;

    return 0;
}

এটি এমএসভিসি, কলং এবং আইসিসিতে প্রত্যাশার মতো সংকলন এবং কাজ করে তবে জিসিসি (ট্রাঙ্ক) সংকলনের সময় operator<<এটি লাইনের জন্য একটি দ্ব্যর্থক ত্রুটি দেয় os << elem << " "। এমনকি এই ত্রুটিটি শুধুমাত্র পতাকাটি -std=c++17বা সংকলনের সময় উপস্থিত হয় -std=c++2a

ত্রুটিটি যুক্তিসঙ্গত বলে মনে হচ্ছে std::string, যেহেতু সংকলকটি একটি বিদ্যমান ফাংশন টেম্পলেট সনাক্ত করে যা বৈশ্বিক পক্ষে operator<<একটি আউটপুট স্ট্রিম এবং একটি গ্রহণ করে basic_string<CharT, Traits, Allocator>, Allocatorটাইপটির সাথে ডিফল্ট হয়ে থাকে std::allocator

আমার প্রশ্নটি হ'ল এটি কেন অন্য 3 সংকলকের সাথে সংকলন করে এবং কাজ করে, আমার বুদ্ধি থেকে, ক্ল্যাং কমপক্ষে, লিনাক্সে জিসিসি হিসাবে একই স্ট্যান্ডার্ড লাইব্রেরি বাস্তবায়ন ব্যবহার করে, সুতরাং এতে একই ফাংশন টেম্পলেট রয়েছে operator<<

ত্রুটিটি রিপোর্ট করা হয়েছে

error: ambiguous overload for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'const std::__cxx11::basic_string<char>')

এবং দুই প্রার্থী

note: candidate: 'std::ostream& operator<<(std::ostream&, const C<T, A>&) [with C = std::__cxx11::basic_string; T = char; A = std::char_traits<char>; std::ostream = std::basic_ostream<char>]'

note: candidate: 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]'

জিসিসি, কলং এবং আইসিসির জন্য সংকলক যুক্তি

-std=c++2a -O3 -Wall -Wextra -Wpedantic -Werror

এমএসভিসির জন্য একটি

/std:c++latest /O2 /W3

বাধ্যতামূলক গডবোল্ট লিঙ্ক: https://godbolt.org/z/R_aSKR

উত্তর:


8

ত্রুটিটি যুক্তিসঙ্গত বলে মনে হচ্ছে std::string, যেহেতু সংকলকটি একটি বিদ্যমান ফাংশন টেম্পলেট সনাক্ত করে যা বৈশ্বিক পক্ষে operator<<একটি আউটপুট স্ট্রিম এবং একটি গ্রহণ করে basic_string<CharT, Traits, Allocator>, Allocatorটাইপটির সাথে ডিফল্ট হয়ে থাকে std::allocator

প্যারামিটারের মতো C<T, A>ধরণের সাথে মিল করার এই ক্ষমতা basic_string<CharT, Traits, Allocator=std::allocator<CharT>>সি ++ 17 এ নতুন, এটি P0522 থেকে আসে । সেই কাগজের আগে, আপনার অপারেটরটিকে প্রার্থী হিসাবে বিবেচনা করা হবে না।

যাইহোক, জঞ্জাল ইচ্ছাকৃতভাবে ডিফল্টরূপে এই বৈশিষ্ট্যটি প্রয়োগ না করার জন্য পছন্দ করে। তাদের অবস্থা থেকে :

একটি ত্রুটি প্রতিবেদনের রেজোলিউশন হওয়া সত্ত্বেও, এই বৈশিষ্ট্যটি সমস্ত ভাষা সংস্করণে ডিফল্টরূপে অক্ষম করা আছে, এবং -frelaxed-template-template-argsক্ল্যাং 4 এর পরে পতাকা সহ স্পষ্টভাবে সক্ষম করা যায় । স্ট্যান্ডার্ডে পরিবর্তনের ক্ষেত্রে টেম্পলেটটি আংশিক অর্ডারের সাথে সম্পর্কিত পরিবর্তনটির অভাব রয়েছে, এর ফলে যুক্তিসঙ্গত এবং পূর্বে-বৈধ কোডের জন্য অস্পষ্টতা ত্রুটি হয়। এই সমস্যাটি শীঘ্রই সংশোধন করা হবে বলে আশা করা হচ্ছে।

আপনি দেখতে পাচ্ছেন যে আপনি যখন পতাকাটি যুক্ত করবেন তখন আপনার কোডটিও ঝাঁকুনিতে অস্পষ্ট হয়ে যায়। আপনার উদাহরণটি এমন ধরণের যুক্তিসঙ্গত এবং পূর্বে-বৈধ কোড যা এই বিপত্তিটি এখানে রক্ষা করছে। একই ধরণের উদাহরণ আমি দেখেছি:

template <class T> struct some_trait;

template <template <class> class C, class A>
struct some_trait<C<A>> { /* ... */ };

template <template <class> class C, class A, class B>
struct some_trait<C<A, B>> { /* ... */ };

some_trait<vector<int>> ঠিক আছে (বাইনারি সংস্করণ ব্যবহার করে) ব্যবহৃত হত, তবে এখন দ্ব্যর্থহীন হয়ে উঠেছে (ইউনারি এবং বাইনারি সংস্করণের মধ্যে)।

এমএসভিসি একই পছন্দটি করতে পারে, তবে আমি জানি না। স্ট্যান্ডার্ড অনুযায়ী সঠিক উত্তরটি কলটি অস্পষ্ট।

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