การเข้าถึงสมาชิกคลาสในคำสั่ง if โดยใช้ std::is_same

ฉันกำลังพยายามแก้ไขปัญหาต่อไปนี้: ฉันต้องการทำคำสั่ง if ที่ทำบางอย่างขึ้นอยู่กับว่าอาร์กิวเมนต์ของเทมเพลตนั้นเป็นวัตถุเฉพาะหรือไม่ และถ้าเป็นเช่นนั้น ให้เรียกใช้ฟังก์ชันสมาชิกของวัตถุ สมมติว่าฉันต้องการ std::string

ตัวอย่าง:

#include <iostream>
#include <string>

template <typename T>
void is_string(const T& arg) {
    if (std::is_same<T, const std::string&>::value)
        std::cout << arg.length() << std::endl;
    else
        std::cout << "The argument is not a string" << std::endl;
}

int main() {
    is_string(0);
    return 0;
}

มันไม่คอมไพล์ โดยมีข้อผิดพลาดดังต่อไปนี้:

types.cpp: In instantiation of ‘void is_string(const T&) [with T = int]’:
types.cpp:13:13:   required from here
types.cpp:7:13: error: request for member ‘length’ in ‘arg’, which is of non-class type ‘const int’
   std::cout << arg.length() << std::endl;

ฉันคิดว่าสิ่งที่ฉันพยายามทำให้สำเร็จอาจไม่สามารถทำได้ใน C ++ 11 แต่ฉันขอขอบคุณข้อเสนอแนะบางประการเกี่ยวกับวิธีการทำสิ่งนั้น


person Jytug    schedule 12.11.2016    source แหล่งที่มา


คำตอบ (2)


ในคำสั่ง if ปกติ ทั้งสองสาขาต้องเป็นรหัสที่ถูกต้อง ในกรณีของคุณ int.length() ไม่สมเหตุสมผล

ใน C ++ 17 คุณสามารถใช้ constexpr if:

if constexpr(std::is_same<T, const std::string&>::value)
    std::cout << arg.length() << std::endl;
else
    std::cout << "The argument is not a string" << std::endl;

สาธิต

ใน C ++ 11 (หรือเก่ากว่า) คุณสามารถใช้การโอเวอร์โหลดเพื่อให้ได้ผลลัพธ์ที่คล้ายกัน:

void foo(std::string const& str){
    std::cout << str.length() << std::endl;
}

template<typename T>
void foo(T const&){
    std::cout << "The argument is not a string" << std::endl;
}

template <typename T>
void is_string(const T& arg) {
    foo(arg);
}

สาธิต

person krzaq    schedule 12.11.2016

void is_string(const std::string& arg) {
  std::cout << arg.length() << std::endl;
}

template <typename T>
void is_string(const T& arg) {
  std::cout << "The argument is not a string" << std::endl;
}

หรือดูว่าคอมไพเลอร์ของคุณรองรับ if constexpr ของ C++17 หรือไม่

person Igor Tandetnik    schedule 12.11.2016