C++ 特定模板类型的函数专门化

C++ 特定模板类型的函数专门化,c++,templates,specialization,C++,Templates,Specialization,考虑以下几点: template <typename TResult> inline TResult _from_string(const string& str); template <> inline unsigned long long _from_string<unsigned long long>(const string& str) { return stoull(str); } 这样我就可以做这样的事情: auto x

考虑以下几点:

template <typename TResult> inline TResult _from_string(const string& str);
template <> inline unsigned long long _from_string<unsigned long long>(const string& str) {
    return stoull(str);
}
这样我就可以做这样的事情:

 auto x = _from_string<vector<int>>("{1,2,3,4,5}");
auto x=_from_字符串(“{1,2,3,4,5}”);
然而,当我编译该函数时(在MSVC 2015下),我得到了错误C2768:“非法使用显式模板参数”,这是有道理的,因为我不应该在专门化中使用新的模板参数


如何重写
向量
专门化,使其工作?

函数模板只能是,不能是;但是类模板可以

// primary class template
template <typename T>
struct X {
    static T _from_string(const string& str);
};

// full specialization for unsigned long long
template <>
struct X<unsigned long long> {
    static unsigned long long _from_string(const string& str) {
        return stoull(str);
    }
};

// partial specialization for vector<T>
template <typename T>
struct X<vector<T>> {
    static vector<T> _from_string(const string& str) {
        // stuff that should be done only if the template parameter if a vector of something
    }
};

// helper function template
template <typename TResult>
inline TResult _from_string(const string& str) {
    return X<TResult>::_from_string(str);
}
//主类模板
模板
结构X{
静态T_来自_字符串(常量字符串和str);
};
//无符号long-long的完全专门化
模板
结构X{
静态无符号长字符串(const string&str){
返回stoull(str);
}
};
//向量的部分特化
模板
结构X{
静态向量来自字符串(常量字符串和str){
//只有当模板参数是某个向量时才应该做的事情
}
};
//辅助函数模板
模板
内联TResult\u from\u字符串(常量字符串和str){
从_字符串(str)返回X::_;
}
然后

auto-x1=_-from_字符串(“12345”);
auto x2=_from_字符串(“{1,2,3,4,5}”);

功能模板只能是,不能是;但是类模板可以

// primary class template
template <typename T>
struct X {
    static T _from_string(const string& str);
};

// full specialization for unsigned long long
template <>
struct X<unsigned long long> {
    static unsigned long long _from_string(const string& str) {
        return stoull(str);
    }
};

// partial specialization for vector<T>
template <typename T>
struct X<vector<T>> {
    static vector<T> _from_string(const string& str) {
        // stuff that should be done only if the template parameter if a vector of something
    }
};

// helper function template
template <typename TResult>
inline TResult _from_string(const string& str) {
    return X<TResult>::_from_string(str);
}
//主类模板
模板
结构X{
静态T_来自_字符串(常量字符串和str);
};
//无符号long-long的完全专门化
模板
结构X{
静态无符号长字符串(const string&str){
返回stoull(str);
}
};
//向量的部分特化
模板
结构X{
静态向量来自字符串(常量字符串和str){
//只有当模板参数是某个向量时才应该做的事情
}
};
//辅助函数模板
模板
内联TResult\u from\u字符串(常量字符串和str){
从_字符串(str)返回X::_;
}
然后

auto-x1=_-from_字符串(“12345”);
auto x2=_from_字符串(“{1,2,3,4,5}”);

您不能部分专门化函数

您不应该完全专门化函数

处理此问题的更好方法是使用重载。返回类型重载只需要一个额外的参数:

template<class T> struct tag_t{constexpr tag_t(){}; using type=T;};
template<class T>constexpr tag_t<T> tag{};

template <typename TResult> inline TResult _from_string(const string& str){
  return _from_string( tag<TResult>, str );
}
以上内容甚至不是一个模板

template <class T, class A>
std::vector<T,A> _from_string(tag_t<std::vector<T,A>>, const string& str) {
  // stuff that should be done only if the target type is a vector of something
}
模板
std::vector _from_string(标记、常量字符串和str){
//只有当目标类型是某事物的向量时才应该做的事情
}
上面是一个模板,但不是一个专门化的模板

作为奖励,如果您在
名称空间foo
中有一个自定义类型
bob
,那么您只需从
名称空间foo
中的字符串(tag\u t,std::string const&)编写
,在大多数情况下称为“ADL”的东西会自动找到它


基于重载的带标记的分派清晰而简单,允许您自定义相关名称空间中的内容。

您不能部分地专门化函数

您不应该完全专门化函数

处理此问题的更好方法是使用重载。返回类型重载只需要一个额外的参数:

template<class T> struct tag_t{constexpr tag_t(){}; using type=T;};
template<class T>constexpr tag_t<T> tag{};

template <typename TResult> inline TResult _from_string(const string& str){
  return _from_string( tag<TResult>, str );
}
以上内容甚至不是一个模板

template <class T, class A>
std::vector<T,A> _from_string(tag_t<std::vector<T,A>>, const string& str) {
  // stuff that should be done only if the target type is a vector of something
}
模板
std::vector _from_string(标记、常量字符串和str){
//只有当目标类型是某事物的向量时才应该做的事情
}
上面是一个模板,但不是一个专门化的模板

作为奖励,如果您在
名称空间foo
中有一个自定义类型
bob
,那么您只需从
名称空间foo
中的字符串(tag\u t,std::string const&)
编写
,在大多数情况下称为“ADL”的东西会自动找到它

基于重载的标记分派清晰而简单,允许您自定义相关名称空间中的内容。

您一定要阅读Herb Sutter。您一定要阅读Herb Sutter。
template <class T, class A>
std::vector<T,A> _from_string(tag_t<std::vector<T,A>>, const string& str) {
  // stuff that should be done only if the target type is a vector of something
}