我有以下特征类( IsLexCastable
)来检查是否可以通过调用 boost::lexical_cast<string>
将类型转换为字符串.它错误地返回 true
对于 vector<int>
.
#include <iostream>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include <boost/lexical_cast.hpp>
using namespace std;
using namespace boost;
namespace std
{
/// Adding to std since these are going to be part of it in C++14.
template <bool B, typename T = void>
using enable_if_t = typename std::enable_if<B, T>::type;
}
template <typename T, typename = void>
struct IsLexCastable : std::false_type
{
};
template <typename T>
struct IsLexCastable<T, std::enable_if_t<std::is_same<std::string, decltype(boost::lexical_cast<std::string>(std::declval<T>()))>::value> > : std::true_type
{
};
int main()
{
vector<int> a = {1, 2, 3};
// cout << lexical_cast<string>(a) << endl;
cout << IsLexCastable<decltype(a)>::value << endl;
return 0;
}
这个程序打印1
,但是 lexical_cast<string>(a)
导致编译错误。什么是正确的实现方式IsLexCastable
?
(这是用 g++48 -std=c++11
和 boost 1.55.0
编译的。)
最佳答案
您的表达式是不够的,因为 lexical_cast
函数模板接受所有内容并且仅通过内部 static_assert
报告错误。而是测试将对象插入 std::ostream
是否有效:
template <typename T, typename=void>
struct IsLexCastable : std::false_type {};
// Can be extended to consider std::wostream as well for completeness
template <typename T>
struct IsLexCastable<T,
decltype(void(std::declval<std::ostream&>() << std::declval<T>()))>
: std::true_type {};
Demo .
the documentation 将该要求称为 OutputStreamable , 以及直接强加到源类型上的。
为什么您的实现不起作用?
decltype
只会导致函数模板的实例化声明。内部静态断言是在 lexical_cast
的定义中触发的,因此不能在 SFINAE 中使用。
[临时安装]/10:
If a function template or a member function template specialization is used in a way that involves overload resolution, a declaration of the specialization is implicitly instantiated (14.8.3).
关于c++ - 检查类型是否可以作为 boost::lexical_cast<string> 的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27709461/