Доступ к члену класса в операторе 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;

Я считаю, что то, чего я пытаюсь достичь, может оказаться невозможным в С++ 11, но я был бы признателен за некоторые предложения о том, как это сделать.


person Jytug    schedule 12.11.2016    source источник


Ответы (2)


В обычном операторе if обе ветви должны быть допустимым кодом. В вашем случае int.length() не имеет смысла.

В С++ 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;

демонстрация

В С++ 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;
}

Или проверьте, поддерживает ли ваш компилятор C++17 if constexpr.

person Igor Tandetnik    schedule 12.11.2016