I have the following traits class(IsLexCastable
) to check if a type can be converted to a string by calling boost::lexical_cast<string>
. It erroneously returns true
for 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;
}
This program prints 1
, but lexical_cast<string>(a)
results in a compile error. What is the right way to implement IsLexCastable
?
(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 {};
Demo.
That requirement is called OutputStreamable by the documentation, and the direct one imposed onto the source type.
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.
[temp.inst]/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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With