检查类型是否可以作为 boost::lexical_cast <string>的参数

Check if type can be an argument to boost::lexical_cast<string>

本文关键字:lt cast string 参数 gt lexical 是否 类型 boost 检查      更新时间:2023-10-16

我有以下特征class(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++11boost 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 {};

演示
该要求被文档称为 OutputStreamable,并且是强加给源类型的直接要求。


为什么您的实现不起作用?

decltype只会导致函数模板声明的实例化。内部静态断言是在lexical_cast的定义中触发的,因此它不能在 SFINAE 中使用。

[温度]/10:

如果函数模板

或成员函数模板专用化 以涉及重载解析的方式使用,专用化声明被隐式实例化 (14.8.3)。

哥伦布的回答回答了这个问题,但我在适应输入流时遇到了问题。我的用例是我想调用lexical_cast从字符串转换为 T.Boost 提供了has_right_shift和has_left_shift,这有效并且应该为类似的结构提供更大的灵活性。

template <typename T, typename=void>
struct IsLexCastable : std::false_type {};
template <typename T>
struct IsLexCastable<T,
        typename std::enable_if<boost::has_right_shift<T>::value>::type>
  : std::true_type {};