টেমপ্লেট মেটা প্রোগ্রামিং


38

কেউ আমাকে বোঝাতে পারেন কেন প্রথম টেমপ্লেট মেটা-প্রোগ্রামিংয়ের উপায়টি অসীম লুপে চলেছে, তবে দ্বিতীয়টি সঠিকভাবে চলে।

#include <iostream>
using namespace std;

template<int N, int M>
struct commondivs {                                              
  static const int val = (N<M) ? commondivs<N,(M-N)>::val : commondivs<(N-M),M>::val;
};

template<int N>
struct commondivs<N,N> {
  static const int val = N;
};


int commondiv(int N, int M){
    if(N==M){
        return N;
    }   
    return (N<M)?commondiv(N,(M-N)):commondiv((N-M),M);     
}

int main() {

    cout << commondivs<9,6>::val << endl;
    cout << commondiv(9,6) << endl;
    return 0;
}


2
লক্ষ্যটি ছিল টেমপ্লেট মেটা প্রোগ্রামিং ব্যবহার করা। constexprএকটি বিকল্প নয়।
এক্সজুল

স্পষ্ট করে তুলতে সি ++ 98 ট্যাগ যুক্ত করা হয়েছে constexprএটি কোনও বিকল্প নয়। (এটি সি ++ 11 এ প্রবর্তিত হয়েছিল)। এটি বিদ্যমান উত্তরগুলি অকার্যকর করে। এক্সজুল, দয়া করে আপনি কোন সি ++ সংস্করণে সীমাবদ্ধ তা স্পষ্ট করুন।
এমসাল্টার

দুঃখিত আমি ট্যাগটি সরিয়েছি।
এক্সজুল

উত্তর:


44
(N<M) ? commondivs<N,(M-N)>::val : commondivs<(N-M),M>::val

এই লাইনটি উভয়ের তাত্পর্য সৃষ্টি করে commondivs<N,(M-N)>::valএবং commondivs<(N-M),M>::val, শর্তটি সংকলন সময়ে জানা থাকলেও এবং এর একটি শাখা কখনই নেওয়া হবে না।

প্রতিস্থাপন ? :সঙ্গে std::conditional_t, যা এই সীমাবদ্ধতা নেই:

static const int val = std::conditional_t<N < M, commondivs<N,(M-N)>, commondivs<(N-M),M>>::val;

15

সমস্যা সব শর্তসাপেক্ষ অপারেটর operands, মূল্যায়ন করা হবে উভয় তাই হয় commondivs<N,(M-N)>এবং commondivs<(N-M),M>instantiated পেতে এবং তাদের valপেতে মূল্যায়ন এবং তারপর রিকার্সিভ টেমপ্লেট ইনস্ট্যান্স বাড়ে।

আপনি কনস্টেক্সপ্র প্রয়োগ করতে পারেন এবং এটি কোনও constexpr staticসদস্য ফাংশনে রাখলে

মানটি যদি হয় trueতবে বিবৃতি-মিথ্যা বাতিল করা হবে (উপস্থিত থাকলে), অন্যথায়, বিবৃতি-সত্যকে বাতিল করা হয়।

template<int N, int M>
struct commondivs {                                              
  constexpr static int get_val() {
    if constexpr (N<M) return commondivs<N,(M-N)>::val; // if true, the else part won't be evaluated
    else return commondivs<(N-M),M>::val;               // vice versa
  }
  static const int val = get_val();
};

লাইভ দেখান


মূল্যায়ন করা বা কেবল তাত্ক্ষণিক?
ড্যানিয়েল ম্যাকলারি

পুনঃটুইট করেছেন শুধু তাত্ক্ষণিক নয়।
গীতিয়ানুয়াও

মানটি ::valঅবশ্যই উভয় শাখায় উত্পন্ন করতে হবে তবে এটি তাত্ক্ষণিকভাবে রয়েছে (একটি স্ট্যাটিক কনস্ট সদস্যের সাথে একটি টেমপ্লেটের)। রান সময় মূল্যায়ন হয় না ... ভাল, সম্ভবত এটি কখনই সংকলন করে না ...
অকেজো

8

টার্নারি অপারেটরটি পছন্দ হয় না if constexpr: যখন কোনও সংকলক এটি দেখে, তখন উভয় শাখার জন্য কোড তৈরি করতে হবে। অন্য কথায়, একটি টেমপ্লেট ইনস্ট্যান্ট করতে commondivs<M, N>, একটি সংকলক উভয় টেম্পলেট commondivs<N, M - N>এবং ইনস্ট্যান্ট করেcommondivs<N - M, M>

এর বিপরীতে, commondiv(N, M - N)এবংcommondiv(N - M, M) দুই ফাংশান কল অনুবাদ করা হয়। কোনটি নেওয়া হয় তা ঠিক করা হবে যখন ফাংশনটি আসলে ডাকা হবে।

সংযোজন.

হলি ব্ল্যাকগ্যাট এর সাথে একটি সমাধান দিয়েছে std::conditional_t। এখানে অন্য একটি:

template<int N, int M>
struct commondivs {                                              
    static constexpr int min = (N < M) ? N : M;
    static constexpr int max = (N < M) ? M : N;
    static constexpr int val = commondivs<min, max - min>::val;
};

template<int N>
struct commondivs<N, N> {
    static constexpr int val = N;
};

0

আপনি অসীম পুনরাবৃত্তি পান কারণ:

static const int val = (N<M) ? commondivs<N,(M-N)>::val : commondivs<(N-M),M>::val;

মোটামুটি প্রোগ্রামিং মোটেও তা নয় কারণ ?:@Eng এর মত বলা হয়েছে, তা নয় constexpr

আপনি @ হলিব্ল্যাকগেটের উত্তরটি দেখতে চান।


1
এটি সাহায্য করবে না। ?:না constexpr
ইভ

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