如何从主模板调用专用模板重载函数?
How can I call the specialized template overloaded function from the main template one?
我在模板 class 中有一个方法可以创建变量的散列。我已经将它的模板专门化为 int、double 和 std::string,就像这样
template<>
class Hash<int>
{
public:
unsigned long operator()(const int& d) const noexcept
{
return d * d;
}
};
template<>
class Hash<double>
{
public:
unsigned long operator()(const double& d) const noexcept
{
long intera = floor(d);
long frazionaria = pow(2, 24) * (d - intera);
return intera * frazionaria;
}
};
template<>
class Hash<std::string>
{
public:
unsigned long operator()(const std::string& d) const noexcept
{
unsigned long hash = 5381;
for (unsigned long i = 0; i << d.length(); i++)
{
hash = (hash << 5) + d[i];
}
return hash;
}
};
然后我创建了相同方法的通用版本,它接受一个模板参数并尝试将其转换为 std::string 然后尝试在其上调用 operator() (我希望调用专业模板一)
unsigned long operator()(const Data& d) const noexcept
{
std::cout<<"Special hash! ";
void *v = (void *)&d;
size_t j = sizeof(d);
std::string s = "";
for (size_t k = 0; k < j; k++)
{
s += (((char *)v)[k]);
}
std::cout<<"Pre-hash: "<<s<<std::endl;
return operator()(s);
}
(它在 class 声明中,而其他 3 个在不同的文件中)
因此,当我在 int、double 或 std::string 上调用 Hash class 的 operator() 时,它工作正常,但是当我尝试在我的另一个 class 上调用它时,我得到此错误:
error: cannot convert ‘std::string’ {aka ‘std::__cxx11::basic_string<char>’} to ‘const lasd::BST<int>&’
35 | return operator()(s);
| ^
| |
| std::string {aka std::__cxx11::basic_string<char>}
所以在我看来它正在尝试再次调用 operator(BST),即使我已经向它传递了一个字符串。有什么办法可以解决这个问题吗?我不关心散列函数不正确,我有一个 uni 分配来这样做,我只需要了解是否有可能从普通模板调用专门的模板函数。
我也试过使用
return operator()<std::string>(s);
正如我在类似问题的其他一些答案中看到的那样,但我收到以下错误:
error: expected primary-expression before ‘>’ token
35 | return operator()<std::string>(s);
| ^
如果我没理解错的话,你的 operator()
需要一个 Hash
实例来调用它的专用 operator()
auto operator()(const Data& d) const noexcept
{
// ....
std::string s = "";
return Hash<std::string>{}.operator()(s);
// ^^^^^^^^^^^^^^^^^^^
// OR simply
// return Hash<std::string>{}(s);
}
更新
根据更新后的 post/ 错误消息,您正在使用尚未声明和定义的特化 Hash<std::string>
。那是在行:
return Hash<std::string>{}(s);
编译器不知道 std::string
的 Hash
专业化。因此,错误!
(一种方法)修复它,你需要拆分声明和定义如下:
template<typename Data> class Hash
{
public:
// declare the operator()
auto operator()(const Data& d) const noexcept;
};
template<> class Hash<int> { /* ...code... */ };
template<> class Hash<double> { /* ...code... */ };
template<> class Hash<std::string> { /* ...code... */ };
// define the operator()
template<typename Data>
auto Hash<Data>::operator()(const Data& d) const noexcept
{
// code!
return Hash<std::string>{}(s);
}
我在模板 class 中有一个方法可以创建变量的散列。我已经将它的模板专门化为 int、double 和 std::string,就像这样
template<>
class Hash<int>
{
public:
unsigned long operator()(const int& d) const noexcept
{
return d * d;
}
};
template<>
class Hash<double>
{
public:
unsigned long operator()(const double& d) const noexcept
{
long intera = floor(d);
long frazionaria = pow(2, 24) * (d - intera);
return intera * frazionaria;
}
};
template<>
class Hash<std::string>
{
public:
unsigned long operator()(const std::string& d) const noexcept
{
unsigned long hash = 5381;
for (unsigned long i = 0; i << d.length(); i++)
{
hash = (hash << 5) + d[i];
}
return hash;
}
};
然后我创建了相同方法的通用版本,它接受一个模板参数并尝试将其转换为 std::string 然后尝试在其上调用 operator() (我希望调用专业模板一)
unsigned long operator()(const Data& d) const noexcept
{
std::cout<<"Special hash! ";
void *v = (void *)&d;
size_t j = sizeof(d);
std::string s = "";
for (size_t k = 0; k < j; k++)
{
s += (((char *)v)[k]);
}
std::cout<<"Pre-hash: "<<s<<std::endl;
return operator()(s);
}
(它在 class 声明中,而其他 3 个在不同的文件中) 因此,当我在 int、double 或 std::string 上调用 Hash class 的 operator() 时,它工作正常,但是当我尝试在我的另一个 class 上调用它时,我得到此错误:
error: cannot convert ‘std::string’ {aka ‘std::__cxx11::basic_string<char>’} to ‘const lasd::BST<int>&’
35 | return operator()(s);
| ^
| |
| std::string {aka std::__cxx11::basic_string<char>}
所以在我看来它正在尝试再次调用 operator(BST),即使我已经向它传递了一个字符串。有什么办法可以解决这个问题吗?我不关心散列函数不正确,我有一个 uni 分配来这样做,我只需要了解是否有可能从普通模板调用专门的模板函数。 我也试过使用
return operator()<std::string>(s);
正如我在类似问题的其他一些答案中看到的那样,但我收到以下错误:
error: expected primary-expression before ‘>’ token
35 | return operator()<std::string>(s);
| ^
如果我没理解错的话,你的 operator()
需要一个 Hash
实例来调用它的专用 operator()
auto operator()(const Data& d) const noexcept
{
// ....
std::string s = "";
return Hash<std::string>{}.operator()(s);
// ^^^^^^^^^^^^^^^^^^^
// OR simply
// return Hash<std::string>{}(s);
}
更新
根据更新后的 post/ 错误消息,您正在使用尚未声明和定义的特化 Hash<std::string>
。那是在行:
return Hash<std::string>{}(s);
编译器不知道 std::string
的 Hash
专业化。因此,错误!
(一种方法)修复它,你需要拆分声明和定义如下:
template<typename Data> class Hash
{
public:
// declare the operator()
auto operator()(const Data& d) const noexcept;
};
template<> class Hash<int> { /* ...code... */ };
template<> class Hash<double> { /* ...code... */ };
template<> class Hash<std::string> { /* ...code... */ };
// define the operator()
template<typename Data>
auto Hash<Data>::operator()(const Data& d) const noexcept
{
// code!
return Hash<std::string>{}(s);
}