我可以输入检查模板参数吗? (C++)

Can I type check a template parameter? (C++)

我想检查给定变量是否为字符。现在,我的函数 returns 一个基于向量元素的字符串。

问题是如果我给它一个字符向量,那么 to_string() 会给我字符 'foo' 的数值。所以我想让它读到的地方:

a b

改为

97 98

我宁愿在函数中实现一些东西也不愿创建重载,因为我已经为参数类型 vector<vector<T>>vector<array<T, 2>> 设置了另外两个重载,它们需要 运行逻辑,总共有六个函数而不是三个函数会很混乱。

   /** to string for vector that has singular elements
     * vtos : vector to string
     **/
    template <class T>
    basic_string<char> vtos (vector<T> &v )
    {
        string ret;
        int i = 0;
    
        for ( T& foo: v )
        {
            ret.append(to_string(foo) + " ");
            if (++i % 10 ==0)
                ret.push_back('\n');
        }
    
        return ret;
    }

++++++++++++++++++++++++++++++++++

编辑: 如果你有 C++17,你可以使用标记的解决方案。我不知道,所以我决定只使用默认参数。

编辑 2:标记的答案现在还包括一个编辑,检查那里是否有 c++17 之前的答案。我也会在这里留下自己的。

template <class T>
basic_string<char> vtos (vector<T> &v, bool isChar=false)
{
    string ret;
    int i = 0;

    for ( T& foo: v )
    {
        if (isChar)
            ret.push_back(foo);
        else
            ret.append(to_string(foo));

        ret.push_back(' ');

        if (++i % 10 ==0)
            ret.push_back('\n');
    }

    return ret;
}

您可以尝试使用 if constexpr 和类型特征 is_same

#include <iostream>
#include <type_traits>
#include <vector>


template <class T>
std::string vtos (const std::vector<T> &v )
{
    std::string ret;
    int i = 0;
    auto to_string = [](const auto& elem)
    {
       if constexpr ( std::is_same_v<T,char> )
       {
           return std::string(1,elem);
       }
       else
       {
          return std::to_string(elem);   
       }
    };
    for (const T& foo: v )
    {
        ret.append(to_string(foo) + " ");
        if (++i % 10 ==0) ret.push_back('\n');
    }
    return ret;
}
int main()
{
   std::cout << vtos(std::vector<char>{'a','b'});
}

:

  • 不要使用 using namespace std;。参见 this post
  • 如果不需要修改,请使用const &而不是&。看:
    • Const correctness
    • 使用 const & 你可以匹配 rvalue reference,就像我的例子。

C++14: 您可以将 if constexpr 替换为 SFINAEDemo

#include <iostream>
#include <type_traits>
#include <vector>

template <class T> 
std::enable_if_t<std::is_same_v<T,char>, std::string>  to_string(const T& elem)
{
    return std::string(1,elem); 
}

template <class T> 
std::enable_if_t<not std::is_same_v<T,char>, std::string> to_string(const T& elem)
{
    return std::to_string(elem); 
}

template <class T>
std::string vtos (const std::vector<T> &v )
{
    std::string ret;
    int i = 0;
    for (const T& foo: v )
    {
        ret.append(to_string(foo) + " ");
        if (++i % 10 ==0) ret.push_back('\n');
    }
    return ret;
}
int main()
{
   std::cout << vtos(std::vector<char>{'a','b'});
   std::cout << vtos(std::vector<int>{12,5});
}

编辑:Evg 更快,如果你post回答我会删除这个