ভেরিয়েবলের ধরণটি কীভাবে পাব?


130

সি ++ তে, কীভাবে কেউ একটি চলকের ধরণ খুঁজে পায়?



7
cout << typid (ভেরিয়েবল) .নাম () << এন্ডল;
এসআরএন

2
অনুসন্ধান ব্যবহার করুন অথবা Google :) stackoverflow.com/questions/81870/print-variable-type-in-c Theharshest দ্রুত: ডি
Kariboo

14
@ কারিবু, আমি গুগল ব্যবহার করেছি এবং এটি আমাকে এখানে পাঠিয়েছে।
মাইকেল ওয়ার্নার

এই প্রশ্নটি যেমন হয় তেমন অস্পষ্ট এবং বিভিন্ন উত্তর দেখার পরেও; এটি কোনওভাবেই পরিষ্কার নয় যে প্রশ্নটি গৃহীত উত্তর চাইছে।
অ্যান্টি হাপালা

উত্তর:


158

আপনি টাইপড অপারেটরটি ব্যবহার করতে পারেন :

#include <typeinfo>
...
cout << typeid(variable).name() << endl;

15
@ ডেভিড - সুতরাং iআপনার সংকলকটিতে পূর্ণসংখ্যার অর্থ। ফিরে আসা নামগুলি মান দ্বারা নির্দিষ্ট করা হয় না।
বো পারসন

11
আমি যখন এটি ভেক্টরে ব্যবহার করি <int> এটি St6vectorIiSaIiEE প্রদান করে। ডব্লিউটিএফ?
বায়ান কুশলেভ

2
@ ববিব্রাউন আপনি একা নন !! google.co.uk/webhp#safe=off&q=St6vectorIiSaIiEE
ধনী ও'কেলি

5
ফেরত নামগুলি typeidখুব সংক্ষিপ্ত, সংকলক-নির্দিষ্ট এবং মানুষের ব্যবহারের উদ্দেশ্যে নয়। আপনি "demangle" তাদেরকে (যে প্রকৃত শব্দটি এর!), হয় ভালো কিছু সঙ্গে কোডে gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html যেমন কমান্ড লাইন ইউটিলিটি সঙ্গে c++filt, অথবা বিভিন্ন অনলাইন demanglers সাথে যেমন demangler.com
সিনকোডেনদা

33

স্থির প্রতিবেদনের জন্য, সি ++ 11 প্রবর্তিত decltypeযা নির্দিষ্ট পরিস্থিতিতে বেশ কার্যকর।


12

আপনার যদি ভেরিয়েবল থাকে

int k;

আপনি এর ধরণটি ব্যবহার করে পেতে পারেন

cout << typeid(k).name() << endl;

নিম্নলিখিত থ্রেডটি এসও তে দেখুন: অনুরূপ প্রশ্ন


9

সি ++ এবং জাভাস্ক্রিপ্টের মধ্যে প্রধান পার্থক্যটি হ'ল সি ++ একটি স্ট্যাটিক-টাইপযুক্ত ভাষা, উইল জাভাস্ক্রিপ্ট গতিশীল।

ডায়নামিক টাইপ করা ভাষাগুলিতে একটি ভেরিয়েবলের মধ্যে যা কিছু থাকে তা থাকতে পারে এবং এর ধরণটি মুহুর্তে মুহুর্তে ধরে রাখা মান দ্বারা দেওয়া হয়। স্ট্যাটিক টাইপ করা ভাষায় ভেরিয়েবলের ধরণ ঘোষিত হয় এবং পরিবর্তন করা যায় না।

ডায়নামিক প্রেরণ এবং অবজেক্ট রচনা এবং সাব টাইপিং (উত্তরাধিকার এবং ভার্চুয়াল ফাংশন) পাশাপাশি স্ট্যাটিক-প্রেরণ এবং সুপারটাইপিং (টেমপ্লেট সিআরটিপি এর মাধ্যমে) হতে পারে, তবে যে কোনও ক্ষেত্রে চলকের ধরণটি অবশ্যই কম্পাইলারের কাছে জানা উচিত।

এটি কী বা কী হতে পারে তা আপনি যদি না জানতে পজিশনে থাকেন তবে ভাষাটির গতিশীল টাইপ-সিস্টেম থাকায় আপনি এমন কিছু নকশা করেছেন।

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


যদি সি ++ এর ডায়নামিক পরিবর্তন হয় তবে আমি মনে করি এটি দুর্দান্ত এবং টাইপফ এবং পার্সিয়ান্ট হবে, পার্সফ্লোট ফাংশনগুলিও কাজে আসবে তবে আমি জানি না কেন সি ++ নির্মাতারা এটিকে খুব শক্ত করে তোলে, উদাহরণস্বরূপ! কে বলছেন কেউট লিখতে ভাল << "স্ট্রিং"
ওয়াকাস তাহির

দৃ determination় সংকল্প সেরা !!!! # স্ট্রিম স্ট্রিং ("1912") অন্তর্ভুক্ত করুন; int strtointval; স্ট্রিংস্ট্রিম (স্ট্র) >> স্ট্রিন্টওয়ালওয়াল;
ওয়াকাস তাহির

@ ওয়াকাস উহ, কি? যে লোকেরা এটি সর্বোত্তম বলে তারাই সেই ভাষাটি সংজ্ঞায়িত করে এমন লোক এবং আইএমওর সাথে চূড়ান্তভাবে কিছু বলা যায় - ভাল কোডিং অনুশীলন, উদাহরণস্বরূপ। আপনি যে মন্তব্যটি পুনরায় লিখতে পারেন তাই এটি আরও অর্থবোধ করে?
ফান্ড মনিকার লসুইট

আমি সম্পূর্ণ একমত। জাভা, সি #, পিএইচপি, পার্ল, পাইথন এবং আরও অনেকগুলি সি এবং সি ++ এ ডিজাইন করা হয়েছিল এবং সেগুলি শুঁয়োপোকা নয়। (আপনি যখন 'অজানা' ডাটাবেসগুলি থেকে ভেরিয়েবল টেবিলগুলি খোলার জন্য একটি ডাটাবেস অ্যাপ্লিকেশন তৈরি করেন তখন আপনার ফিল্ড টাইপটি ভেরিয়েবল স্কিম এবং ভাইস ভেরাতে 'খুব' ডাইমানিক উপায়ে নিয়ন্ত্রণ করতে হবে;))
টোমেনএস

@ টমিজএনএস: না এগুলি সি এবং সি ++ তে লেখা হয়েছে, নকশাকৃত নয় । তারা তাদের কাজগুলি করার জন্য ডিজাইন করা হয়েছে। তাদের গতিশীল ধরণের রয়েছে এমনকি সি এবং সি ++ না করলেও। এটি এর সাথে অদ্ভুত কিছু নয়।
এমিলিও গারাভাগলিয়া

8

সাধারণত, সি ++ এর মধ্যে একটি ভেরিয়েবলের ধরণটি সন্ধান করা ভুল প্রশ্ন question এটি এমন কিছু হতে পারে যা আপনি পদ্ধতিগত ভাষাগুলির সাথে বহন করেন যেমন উদাহরণস্বরূপ সি বা পাস্কাল।

আপনি যদি টাইপের উপর নির্ভর করে বিভিন্ন আচরণের কোড করতে চান, তবে উদাহরণস্বরূপ ফাংশন ওভারলোডিং এবং অবজেক্টের উত্তরাধিকার সম্পর্কে জানার চেষ্টা করুন । এটি আপনার সি ++ এর প্রথম দিনটিতে তাত্ক্ষণিকভাবে বোঝায় না, তবে এটি চালিয়ে যান।


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

যে কোনও নিয়মের মতো, এখানেও ব্যতিক্রম রয়েছে (তাই আমার 'সাধারণত'!), এবং ধারকগুলি টাইপ থিওরিতে জটিলতা যুক্ত করে। আমি পলিমার্ফিক-অবজেক্টস-এর পাত্রে কখনই অত্যধিক পছন্দ করি না ... বেশিরভাগ ক্ষেত্রে, টেম্প্লেটেড ইউনিফর্ম কনটেইনার ধরণের প্রকার যথেষ্ট এবং আরও পরিষ্কার er
পন্টাস গ্যাজে

আপনি টেমপ্লেট ব্যবহার করবেন না?
ব্রায়ান গ্রেস

6

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

পলিমারফিজম ব্যবহার না করে প্রতিটি ধরণের সমর্থিত ফাংশনের একটি উদাহরণ তৈরি করা এটি অনেক বেশি কমপ্যাক্ট এবং রক্ষণাবেক্ষণযোগ্য। এমনকি সেই ক্ষেত্রে আমি এই কৌশলটি কেবল একবারে ফাংশনটির বডি লিখতে ব্যবহার করতে পারি:

নোট করুন যেহেতু কোডটি টেমপ্লেটগুলি ব্যবহার করে, নীচে স্যুইচ বিবৃতিটি সমস্ত মিথ্যা কেস, এএফআইকে অপ্টিমাইজ করে শুধুমাত্র একটি কোড ব্লকে স্থিতিশীলভাবে সমাধান করতে হবে।

এই উদাহরণটি বিবেচনা করুন, যেখানে টি রূপের তুলনায় অন্যরকম একটি রূপান্তর পরিচালনা করতে আমাদের প্রয়োজন হতে পারে। আমি এটি ক্লাস স্পেশালাইজেশনের জন্য হার্ডওয়্যার অ্যাক্সেসের জন্য ব্যবহার করি যেখানে হার্ডওয়্যারটি মাই ক্লাসএ বা মাই ক্লাসবি টাইপ ব্যবহার করবে। অমিলের ভিত্তিতে, আমার ডেটা রূপান্তর করতে সময় কাটাতে হবে।

switch ((typeid(T)) {
  case typeid(myClassA):
    // handle that case
    break;
  case typeid(myClassB):
    // handle that case
    break;
  case typeid(uint32_t):
    // handle that case
    break;
  default:
    // handle that case
}

1
টাইপআইডি: আমি আরডিনোতে টাইপড () ব্যবহার করতে পারিনি। এছাড়াও টাইপড () একটি রানটাইম চেক, সময় সংকলন নয় তাই এটি অনুকূলিত কোড উত্পন্ন করতে ব্যবহার করা যাবে না।
ড্যান ট্রুং

1
হ্যাঁ, না, আপনি যা ভেবেছিলেন এটি এটি করে না। typeidসংজ্ঞা অনুসারে - কেবল কোনও স্থিতিশীল, সংকলন-সময় চেক হতে পারে না - সুতরাং এটি কোনও অপ্টিমাইজেশনের সুবিধার্থ করে না। For a template function, I need to special case the code based on the template variableঠিক আছে, তাই আপনি যা চান তা হ'ল সিআরটিপি আইডিয়ামের মাধ্যমে স্থির বহুপদীতা। এটি ঠিক যা অর্জন করে।
আন্ডারস্কোর_ডি

4

আমি নিশ্চিত না আমার উত্তরটি সাহায্য করবে কিনা।

সংক্ষিপ্ত উত্তরটি হ'ল, এটি ব্যবহার করার জন্য আপনার আসলে কোনও ভেরিয়েবলের প্রকারটি জানতে / জানতে চান না।

আপনার যদি কোনও স্ট্যাটিক ভেরিয়েবলে কোনও প্রকারের প্রয়োজন হয় তবে আপনি কেবল অটো ব্যবহার করতে পারেন।

আরও পরিশীলিত ক্ষেত্রে যেখানে আপনি ক্লাস বা কাঠামোতে "অটো" ব্যবহার করতে চান, আমি ডিক্লাইপযুক্ত টেম্পলেট ব্যবহারের পরামর্শ দেব।

উদাহরণস্বরূপ, বলুন যে আপনি অন্য কারওের গ্রন্থাগার ব্যবহার করছেন এবং এটিতে "অজানা_ভার" নামে একটি ভেরিয়েবল রয়েছে এবং আপনি এটি কোনও ভেক্টর বা কাঠামোতে রাখতে চান, আপনি এটি সম্পূর্ণরূপে করতে পারেন:

template <typename T>
struct my_struct {
    int some_field;
    T my_data;
};
vector<decltype(unknown_var)> complex_vector;
vector<my_struct<decltype(unknown_var)> > simple_vector

আশাকরি এটা সাহায্য করবে.

সম্পাদনা: ভাল পরিমাপের জন্য, আমি এখানে সবচেয়ে জটিল বিষয়টি ভাবতে পারি: অজানা প্রকারের একটি বৈশ্বিক পরিবর্তনশীল। এই ক্ষেত্রে আপনার সি ++ 14 এবং টেম্পলেট ভেরিয়েবলের প্রয়োজন হবে।

এটার মতো কিছু:

template<typename T> vector<T> global_var;

void random_func (auto unknown_var) {
    global_var<decltype(unknown_var)>.push_back(unknown_var);
}

এটি এখনও কিছুটা ক্লান্তিকর তবে এটি টাইপহীন ভাষাগুলিতে পৌঁছানোর মতোই কাছাকাছি। আপনি যখনই টেম্পলেট পরিবর্তনশীল উল্লেখ করেন কেবলমাত্র তা নিশ্চিত করুন, সর্বদা সেখানে টেমপ্লেটের বিশদকরণ রাখুন।



0

আপনার যদি কোনও শ্রেণি এবং একটি পরিচিত ধরণের মধ্যে তুলনা করা প্রয়োজন, উদাহরণস্বরূপ:

class Example{};
...
Example eg = Example();

আপনি এই তুলনা লাইন ব্যবহার করতে পারেন:

bool isType = string( typeid(eg).name() ).find("Example") != string::npos;

typeidনামেরটিতে স্ট্রিং টাইপ রয়েছে কিনা তা যাচাই করে (টাইপড নামটিতে অন্যান্য ম্যাঙ্গেলযুক্ত ডেটা রয়েছে তাই এর s1.find(s2)পরিবর্তে এটি করা ভাল ==)।


-2

আপনি অবশ্যই যেতে পারেন typeid(x).name()যেখানে এক্স পরিবর্তনশীল নাম। এটি প্রকৃতপক্ষে ডেটা টাইপের জন্য একটি চৌম্বক চর পয়েন্টার দেয়। এখন, নীচের কোডটি দেখুন।

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n = 36;
    char c = 'A';
    double d = 1.2;
    if(*(typeid(n).name()) == 'i'){
        cout << "I am an Integer variable" << endl;
    }
    if(*((char *) typeid(d).name()) == 'd'){
        cout << "I am a Double variable" << endl;
    }
    if(*((char *) typeid(c).name()) == 'c'){
        cout << "I am a Char variable" << endl;
    }
    return 0;
}

কিভাবে প্রথম এবং দ্বিতীয় উভয় কাজ করে তা লক্ষ্য করুন।


প্রথম অক্ষর দ্বারা প্রকারটি সনাক্ত করা খুব খারাপ ধারণা।
দিমিত্রি কুজমিনভ

আপনি দয়া করে আরও নির্দিষ্ট দিমিত্রি হতে পারেন? আমি এখানে আপনার পয়েন্ট পেলাম না।
পাইকাচু

এটি কেবল সংক্ষিপ্ত করা যেতে পারে std::cout << "I'm a variable of type " << typeid(n).name()। (একটি / একটি শৈলী রোধ করার জন্য শব্দযুক্ত, তবে এটি অন্য চেকের সাহায্যে স্থির করা যেতে পারে)। তবুও, যদি আপনি একেবারে একটি তুলনা চাই, এটা এত ভালো করতে করতেtypeid(n) == typeid(int)
Zoe
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.