nab*_*lke 3 c++ templates boost
我有一个模板方法,有两个专门版本的类型bool和vector<string>.
基础版:
template <class T>
const T InternGetValue(const std::string& pfad) const
{
...
}
Run Code Online (Sandbox Code Playgroud)
专业版:
template <>
const bool InternGetValue(const std::string& pfad) const
{
...
}
template <>
const std::vector<std::string> InternGetValue< std::vector<std::string>>(const std::string& pfad) const
{
...
}
Run Code Online (Sandbox Code Playgroud)
现在我想实现一个接受所有类型或vector<aritmethic_data_type>类似的特化.vector<double> vector<int>vector<float>
我可以通过为上述类型编写重载来实现这一点,但我有兴趣通过另一个专业化实现我的目标.
这是我到目前为止所尝试的(导致错误'非法使用显式模板参数'):
template <class T>
const std::vector<T> InternGetValue< std::vector<T>>(const std::string& pfad, typename boost::enable_if<boost::is_arithmetic<T>>::type* dummy = 0) const
{
}
Run Code Online (Sandbox Code Playgroud)
我认为std::enable_if和std::is_integral在一起可以解决这个问题:
template<typename T>
std::vector<typename std::enable_if<std::is_integral<T>::value, T>::type>
f(const std::string& d);
Run Code Online (Sandbox Code Playgroud)
如果std::没有,请尽可能使用boost::.它有它们.
好的,很复杂,但是我一切正常。我不能只检查第一个(默认)函数重载内is_integral的value_type类型,因为这将导致SFINAE删除非向量的重载。
与Nawaz的解决方案不同,这不需要添加虚拟参数,但是确实需要默认功能模板上的enable_if条件。
这适用于VS2010。
#include <vector>
#include <string>
#include <type_traits>
using namespace std;
template <typename T> struct is_vector { static const bool value = false; };
template <typename T> struct is_vector< std::vector<T> > { static const bool value = true; };
// metafunction to extract what type a vector is specialised on
// vector_type<vector<T>>::type == T
template <class T>
struct vector_type
{
private:
template <class T>
struct ident
{
typedef T type;
};
template <class C>
static ident<C> test(vector<C>);
static ident<void> test(...);
typedef decltype(test(T())) vec_type;
public:
typedef typename vec_type::type type;
};
// default version
template <class T>
const typename enable_if<!is_vector<T>::value || !is_integral<typename vector_type<T>::type>::value, T>::type
InternGetValue(const std::string& pfad)
{
return T();
}
// bool specialisation
template <>
const bool
InternGetValue<bool>(const std::string& pfad)
{
return true;
}
// vector<string> specialisation
template <>
const vector<string>
InternGetValue<vector<string>>(const std::string& pfad)
{
return vector<string>();
}
// vector<T> specialisation (where T is integral)
template <class T>
const typename enable_if<is_vector<T>::value && is_integral<typename vector_type<T>::type>::value, T>::type
InternGetValue(const std::string& pfad)
{
return T();
}
int main()
{
string x;
auto a = InternGetValue<int>(x);
auto b = InternGetValue<bool>(x);
auto c = InternGetValue<vector<string>>(x);
auto d = InternGetValue<vector<pair<int, int>>>(x);
auto e = InternGetValue<vector<int>>(x);
}
Run Code Online (Sandbox Code Playgroud)