c++ templateの特殊化について

投稿者: Anonymous

c++のテンプレートで

template<class T>
T get(std::string str)
{
if (std::is_signed<T>)
{
    return std::stoll(str);
}
if(std::is_unsigned_v<T>)
{
    return std::stoull(str);
}
if(std::is_floating_point_v<T>)
{
    return std::stold(str);
}
return T(str);
}

みたいなことをコンパイル時に、
整数なら

template<class T>
T get(std::string str)
{
return std::stoll(str);
}

浮動小数少数なら

template<class T>
T get(std::string str)
{
return std::stold(str);
}

それ以外なら

template<class T>
T get(std::string str)
{
    return T(str);
}

のように分けて実装したいのですが
いちいち型ごとに

template<>
int get<int>(std::string str)
{
    return std::stold(str);
}

とするのは面倒なのでもっと効率的な書き方は存在しませんか?

解決

C++11にも対応させるなら以下のように型特性によるオーバーロードを使えばできなくもないですが、C++17以降への対応で良いならif constexpr文を使った方がはるかに楽ですね。

#include <type_traits>
#include <string>
#include <iostream>


template <class T>
T get(const std::string &str,
      typename std::enable_if<
          std::is_integral<T>::value && std::is_signed<T>::value
      >::type * = nullptr)
{
    return std::stoll(str);
}

template <class T>
T get(const std::string &str,
      typename std::enable_if<
          std::is_integral<T>::value && std::is_unsigned<T>::value
      >::type * = nullptr)
{
    return std::stoull(str);
}

template <class T>
T get(const std::string &str,
      typename std::enable_if<
          std::is_floating_point<T>::value
      >::type * = nullptr)
{
    return std::stold(str);
}

template <class T>
T get(const std::string &str,
      typename std::enable_if<
          !std::is_integral<T>::value && !std::is_floating_point<T>::value
      >::type * = nullptr)
{
    return str;
}


int main()
{
    auto si = get<int>("-123");
    std::cout << "si = " << si << "n";

    auto ui = get<unsigned int>("123");
    std::cout << "ui = " << ui << "n";

    auto df = get<double>("123.4");
    std::cout << "df = " << df << "n";

    auto str = get<std::string>("xyz");
    std::cout << "str = " << str << "n";
}
回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *