Pradhan Pradhan - 5 months ago 24
C++ Question

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

I have the following traits class(

) to check if a type can be converted to a string by calling
. It erroneously returns

#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;

This program prints
, but
results in a compile error. What is the right way to implement

(This was compiled with
g++48 -std=c++11
, and
boost 1.55.0


Your expression is not sufficient, as the lexical_cast function template takes everything and only reports errors via an internal static_assert. Instead test whether inserting the object into an std::ostream is valid:

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 {};

That requirement is called OutputStreamable by the documentation, and the direct one imposed onto the source type.

Why did your implementation not work?

decltype only causes the instantiation of the declaration of a function template. The internal static assertion is triggered inside the definition of lexical_cast though, hence it cannot be used in SFINAE.


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).