专门化模板成员函数
Specializing template member function
我正在尝试指定一个模板类的函数,该函数只有在使用特定类型(KEY作为std::string
,VALUE作为std::string
)创建该类的对象时才有效。
我的模板(Dictionary.h
),简化:
#ifndef QB_DICTIONARY_H
#define QB_DICTIONARY_H
#include <map>
#include <string>
namespace QB {
template<typename KEY, typename VALUE, typename COMPARE = std::less<KEY>>
class Dictionary {
public:
typedef typename std::map<KEY, VALUE, COMPARE>::iterator iterator;
typedef typename std::map<KEY, VALUE, COMPARE>::const_iterator const_iterator;
Dictionary() {
}
Dictionary(const std::map<KEY, VALUE, COMPARE> & value) {
this->value = value;
}
typename iterator begin() {
return value.begin();
}
typename const_iterator begin() const {
return value.cbegin();
}
typename iterator end() {
return value.end();
}
typename const_iterator end() const {
return value.cend();
}
// Trying to have the function work only when the template KEY and VALUE are of type std::string
const std::string implode<std::string, std::string>(const std::string & valueSeparator, const std::string & pairSeparator) const {
std::string result;
for (iterator i = begin(); i != end(); i++) {
if (i != begin()) {
result += pairSeparator;
}
result += iterator->first;
result += valueSeparator;
result += iterator->second;
}
return result;
}
private:
std::map<KEY, VALUE, COMPARE> value;
};
}
#endif
内爆函数是我正在尝试实现的函数。尝试在以下位置编译上述结果:
1>d:cloud storageonedriveprojectsqbqbdictionary.h(115): error C2143: syntax error: missing ';' before '<'
1> d:cloud storageonedriveprojectsqbqbdictionary.h(133): note: see reference to class template instantiation 'QB::Dictionary<KEY,VALUE,COMPARE>' being compiled
1>d:cloud storageonedriveprojectsqbqbdictionary.h(115): error C2334: unexpected token(s) preceding '{'; skipping apparent function body
我不确定该如何实现。有什么提示吗?
编辑:
我在尝试@TartanLlama的答案时遇到了一些新问题。
我当前的代码如下(省略了不相关的部分):Dictionary.h
:
#ifndef QB_DICTIONARY_H
#define QB_DICTIONARY_H
#include <map>
#include <string>
#include <type_traits>
namespace QB {
template<typename KEY, typename VALUE, typename COMPARE = std::less<KEY>>
class Dictionary {
public:
// ...
const std::string implode(const std::string &, const std::string &) const;
// ...
};
template<typename K=KEY, typename V=VALUE, typename COMPARE = std::less<KEY>>
std::enable_if_t<std::is_same<std::string, K>{} && std::is_same<std::string, V>{}, const std::string> Dictionary<K, V, COMPARE>::implode(const std::string & valueSeparator, const std::string & pairSeparator) const {
// ...
}
}
#endif
您正试图显式地专门化implode
,但它不是一个模板。
如果KEY
和VALUE
是std::string
:,则只能使用SFINAE启用该功能
template <typename K=KEY, typename V=VALUE>
std::enable_if_t<std::is_same<std::string, K>{} &&
std::is_same<std::string, V>{},
const std::string>
implode(const std::string & valueSeparator,
const std::string & pairSeparator) const {
//...
}
如果函数被实例化为错误的Dictionary
专用化:,则可以使用static_assert
来发出错误
implode(const std::string & valueSeparator,
const std::string & pairSeparator) const {
static_assert(std::is_same<std::string, K>{} &&
std::is_same<std::string, V>{},
"KEY and VALUE must be std::string");
//...
}
您可以通过在类定义之外显式实例化方法成员来进行专门化:
template<> std::string QB::Dictionary<std::string, std::string>::implode(const std::string & valueSeparator, const std::string & pairSeparator) const {
std::string result;
for (const_iterator i = begin(); i != end(); i++) {
if (i != begin()) {
result += pairSeparator;
}
result += i->first;
result += valueSeparator;
result += i->second;
}
return result;
}
实时代码
注意,我已经修复了其他错误(无需在返回方法类型中添加typename,使用const_iterator…)
相关文章:
- 如何使用指针传递给函数的数组中对象的函数成员
- c++构造函数成员初始化:传递参数
- 创建 std::函数,它返回具有函数成员值的变量.分段错误
- 如何在C++通过公共函数访问私有函数成员?
- 解释了构造函数成员初始化列表
- 调用std::函数成员时内存损坏
- 是否可以为模板类的模板函数成员设置别名?
- 捕获 lambda 函数C++成员变量
- 构造函数成员初始值设定项跨成员列出,安全吗?
- 获取与在模板参数中传递的函数成员类型相同的类
- 如何从公共函数成员访问地图私有成员
- C 构造函数成员分配优化
- 使用命名空间进行函数成员定义
- 函数成员作为 CUDA 内核的参数
- 模板基类函数成员的别名
- 函数成员中用于void和继承的enable_if
- 头文件中是否定义了一个很长的Class函数成员
- 类内/构造函数成员初始化
- 使用指向部分专用函数成员的指针自动填充向量
- 指向函数成员的指针