我可以输入检查模板参数吗? (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
替换为 SFINAE
。 Demo
#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回答我会删除这个
我想检查给定变量是否为字符。现在,我的函数 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
替换为 SFINAE
。 Demo
#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回答我会删除这个