বিভিন্ন সি ++ কম্পাইলারের মধ্যে অটো প্রকারের তুলনামূলক মিল ded


10

সুতরাং, আমি আধুনিক সি ++ এর কিছু স্বাদে ডট পণ্য ( https: //en.wik વિક.org / উইকি / ডট_প্রডাক্ট ) বাস্তবায়নের চেষ্টা করছি এবং নিম্নলিখিত কোডটি নিয়ে এসেছি:

#include <iostream>

template<class... Args>
auto dot(Args... args)
{
    auto a = [args...](Args...)
    { 
        return [=](auto... brgs)
        {
            static_assert(sizeof...(args) == sizeof...(brgs));

            auto v1 = {args...}, i1 = v1.begin();
            auto v2 = {brgs...}, i2 = v2.begin();
            typename std::common_type<Args...>::type s = 0;

            while( i1 != v1.end() && i2!= v2.end())
            {
                s += *i1++ * *i2++;
            } 
            return s;
        };
    };
  return a(std::forward<Args>(args)...);
}

int main()
{
    auto a = dot(1,3,-5)(4,-2,-1);
    std::cout << a << std::endl;
}

অনলাইন: https://gcc.godbolt.org/z/kDSney এবং এছাড়াও: সিপ্পিনসাইটস

প্রনয়ন এবং, executes চমত্কারভাবে সঙ্গে উপরের কোড g++অবশ্য clang(এবং iccএবং msvc) এটা চোক:

clang++ ./funcpp.cpp --std=c++17                                                                                                                                                                                                                                                        
./funcpp.cpp:12:4: error: 'auto' deduced as 'std::initializer_list<int>' in declaration of 
        'v1' and deduced as 'const int *' in declaration of 'i1'
                        auto v1 = {args...}, i1 = v1.begin();
                        ^         ~~~~~~~~~       ~~~~~~~~~~
./funcpp.cpp:28:11: note: in instantiation of function template specialization 
        'dot<int, int, int>' requested here
        auto a = dot(1,3,-5)(4,-2,-1);
                 ^
1 error generated.

এখন, আমি যদি সংজ্ঞার ভেঙ্গে v1, v2, i1, i2মত:

auto v1 = {args...} ;
auto i1 = v1.begin();
auto v2 = {brgs...};
auto i2 = v2.begin();

clangএবং msvcকোন সমস্যা নেই, iccএখনও chokes:

<source>(10): error: static assertion failed

                static_assert(sizeof...(args) == sizeof...(brgs));

                ^

          detected during instantiation of "auto dot(Args...) [with Args=<int, int, int>]" at line 30

compilation aborted for <source> (code 2)

Execution build compiler returned: 2

তবে যদি আমি আপত্তিকর অপসারণ static_assertতারপর iccপারেন কোড কম্পাইল কোন বিষয় আছে।

এবং (সাধারণ) প্রশ্নের পাশে: যা সঠিক এবং কেন :) এর নিরঙ্কুশ প্রশ্নটি হ'ল:

মতে [dcl.spec.auto]:

স্থানধারকের ধরণের প্রতিস্থাপনের ধরণটি যদি প্রতিটি ছাড়ের ক্ষেত্রে একই না হয় তবে প্রোগ্রামটি দুর্গঠিত

clangসঠিকভাবে চিহ্নিত করা হয়েছে যে প্রশ্নে রেখায় দুটি ভিন্ন ধরণের সংজ্ঞা দেওয়া আছে: 'auto' deduced as 'std::initializer_list<int>' in declaration of 'v1' and deduced as 'const int *' in declaration of 'i1'সুতরাং আমি আপনার মতামত শুনতে চাই কিনা:

  • g ++ আমার জ্ঞান থেকে এই নির্দিষ্ট পরিস্থিতি বিবেচনা করে ( https://gcc.gnu.org/onlinesocs/gcc-9.2.0/gcc/C_002b_002b- এক্সটেনশনস html#C_002b_002b- এক্সটেনশানগুলি বিবেচনা করে ) আমি কি কিছু অনাবন্ধিত জি ++ এক্সটেনশানকে আঘাত করেছি? একটি স্বয়ংক্রিয় ঘোষণার তালিকায় বিভিন্ন ধরণের সঠিকভাবে পরিচালনা করে,
  • বা কোনও সুযোগে জি ++ দুটি প্রকারকে আলাদা হতে ছাড়েনি (... এইচএম ...)
  • অথবা অন্য কিছু?

এই দীর্ঘ প্রশ্নটি পড়ার জন্য ধন্যবাদ। (বোনাস হিসাবে যদি কেউ উত্তর দিতে পারে যে কেন iccব্যর্থ হয় তবে static_assertদুর্দান্ত হবে))


1
std::forward<Args>(args)এখানে ব্যবহার কি ?
ইভ

test.cpp: ফাংশনে 'int main ()': test.cpp: 4: 5: ত্রুটি: 'অটো': 'লং ইনট' এবং তারপরে 'ডাবল' 4 এর জন্য বেমানান ছাড় স্বয়ং i = 0 l, f = 0.0; | + G জি ++ সহ, সুতরাং দেখে মনে হয় এটি সাধারণভাবে এটি প্রসারিত হয় না।
n314159

প্রকারগুলি মুদ্রণ আমাদের দেয়: স্টাড :: আর্টিমাইজার_লিস্ট <int>, ইন্ট কনস্ট * এসটিডি :: ইনিশিয়ালার_লিস্ট <int>, জি ++ তে ইনস্ট কনস্ট *, সুতরাং এটি বিভিন্ন প্রকারকে ছাড়িয়ে যায়।
n314159

3
জিসিসি সংকলন করে না auto v = { 1, 2, 3 }, i = v.begin(); । বুঝতে হবে না যে এটি একই ইনসিডে ল্যাম্বদা সংকলন করে। সর্বনিম্ন উদাহরণ: gcc.godbolt.org/z/a5XyxU । এমনকি এটি কোনও ব্যবহারকারী-সংজ্ঞায়িত ফান্টারের ভিতরেও সংকলন করে: gcc.godbolt.org/z/eYutyK , বা একটি টেম্পলেট ফাংশন: gcc.godbolt.org/z/jnEYXh
ড্যানিয়েল ল্যাঙ্গার

2
আমি মনে করি খুব ন্যূনতম উদাহরণটি হ'ল template <typename T> void f(T a) { auto v = {a}, i = v.begin(); }, যখন অনুরোধ করা হয়, যেমন f(1);void f(int a) { /* same body */ }সংকলনের ত্রুটির কারণ হিসাবে পুনরায় লিখিত ।
ড্যানিয়েল ল্যাঙ্গার

উত্তর:


2

আমার মন্তব্য থেকে প্রসারিত:

g ++ সর্বদা এটি করে না, উদাহরণটি বিবেচনা করুন auto i = 0l, f = 0.0;, এটি ত্রুটি দেয়:

test.cpp: In function int main()’:
test.cpp:4:5: error: inconsistent deduction for auto’: long int and then double
    4 |     auto i = 0l, f = 0.0;

যদি আমরা আপনার প্রোগ্রামটি সংকলন করি এবং ভেরিয়েবলগুলির প্রকারগুলি ( এই পদ্ধতি সহ ) মুদ্রণ করি তবে আমরা নিম্নলিখিত আউটপুটটি পাই:

v1: std::initializer_list<int>, i1: int const*
v2: std::initializer_list<int>, i2: int const*

-std=c++17 -pedantic -Wall -Wextraকোনও সতর্কতা বা ত্রুটি ছাড়াই পতাকা সহ জিসিসি সংস্করণ 9.2.0 ব্যবহার করা ।

স্ট্যান্ডার্ড সম্পর্কে আপনার মন্তব্যে এই প্রোগ্রামটি দুর্গঠিত এবং মানটি নির্দিষ্ট করে যে অন্যথায় নির্দিষ্ট না করা পর্যন্ত (যা এই ক্ষেত্রে এটি নয়) নির্দিষ্ট করে একটি ডায়গনিস্টিক বার্তা (সতর্কতা বা ত্রুটি) নির্গত করা উচিত। তাই আমি বলব যে এটি জিসিসিতে একটি বাগ bu

এটি একটি পরিচিত বাগ


যেহেতু এটি খুব সুবিধাজনক বাগ ... কিছু এটির বৈশিষ্ট্য হিসাবে যুক্তিযুক্ত হতে পারে: ডি আপনার অন্তর্দৃষ্টিগুলির জন্য ধন্যবাদ!
ফেরেঙ্ক ডেক

কেউ যদি এ g++সম্পর্কে কোনও ত্রুটি দায়ের করতে পারে তবে দুর্দান্ত হবে ।
আন্ডারস্কোর_২

1
আমি এর আগে কখনও করিনি তবে আমি কয়েক ঘন্টার মধ্যে এটি দেখতে পারি।
n314159

gcc.gnu.org/bugzilla/show_bug.cgi?id=92509 আশা করি এটি একটি বুদ্ধিমান বাগ রিপোর্ট।
n314159

0

static_assertব্যর্থ আইসিসি উপর স্পষ্টভাবে একটি বাগ সংশোধন করা হয়। আমি static_assertএকটি পৃথক ফাংশন এ সরানো একটি সহজ workaround পেয়েছি । খুব মার্জিত সমাধান নয়, তবে এটি কাজ করে।

সামান্য পরিবর্তন সহ, এটি জিসিসিসি, কলং এবং আইসিসির সাথে সংকলিত কোড:

template<std::size_t size, class... Args>
void args_no_guard(Args... args)
{
    static_assert(sizeof...(args) == size);
}

template<class... Args>
auto dot(Args... args)
{
    return [=](auto... brgs)
    {
        constexpr auto n = sizeof...(args);
        args_no_guard<n>(brgs...);

        using T = std::common_type_t<decltype(args)..., decltype(brgs)...>;
        const T v1[]{static_cast<T>(args)...};
        const T v2[]{static_cast<T>(brgs)...};

        T dot = 0;
        for (std::size_t i = 0; i < n; ++i)
            dot += v1[i] * v2[i];
        return dot;
    };
}

আইসিসির বিপক্ষে কি কোনও বাগ আছে? :-)
আন্ডারস্কোর_দিন

আপনি বলেছিলেন যে আইসিসিতে স্পষ্টত একটি বাগ রয়েছে, তাই আমি অবাক হয়েছি যে তাদের কাছে ইতিমধ্যে কারও দ্বারা জমা দেওয়া এই বাগের কোনও প্রতিবেদন আছে। যদি তা না হয় তবে এটি তৈরি করার জন্য এটি ভাল সময় হতে পারে।
আন্ডারস্কোর_দিন

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