সুতরাং, আমি আধুনিক সি ++ এর কিছু স্বাদে ডট পণ্য ( 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
দুর্দান্ত হবে))
auto v = { 1, 2, 3 }, i = v.begin();
। বুঝতে হবে না যে এটি একই ইনসিডে ল্যাম্বদা সংকলন করে। সর্বনিম্ন উদাহরণ: gcc.godbolt.org/z/a5XyxU । এমনকি এটি কোনও ব্যবহারকারী-সংজ্ঞায়িত ফান্টারের ভিতরেও সংকলন করে: gcc.godbolt.org/z/eYutyK , বা একটি টেম্পলেট ফাংশন: gcc.godbolt.org/z/jnEYXh ।
template <typename T> void f(T a) { auto v = {a}, i = v.begin(); }
, যখন অনুরোধ করা হয়, যেমন f(1);
। void f(int a) { /* same body */ }
সংকলনের ত্রুটির কারণ হিসাবে পুনরায় লিখিত ।
std::forward<Args>(args)
এখানে ব্যবহার কি ?