如何从主模板一个调用专用模板重载函数?

发布于 2025-02-02 17:59:11 字数 2357 浏览 1 评论 0原文

我有一个模板类中的方法,该类别创建了一个变量的哈希。我已经将其模板专门为int,double and 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);
    }

(在类声明中,其他3个在其他文件中) 因此

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>}

​即使我将字符串传递给了它,它也试图再次致电操作员(BST)。有什么办法可以解决这个问题吗?我不在乎哈希函数不正确,我有这样做的Uni分配,我只需要了解是否可以从普通模板ONE调用专用模板功能。 我还尝试过

return operator()<std::string>(s);

在一个类似问题的其他答案中看到的,但是我会收到以下错误:

error: expected primary-expression before ‘>’ token
   35 |                         return operator()<std::string>(s);
      |                                                      ^

https://gcc.godbolt.org/z/9oz8gf9am

I have a method inside a templated class that creates a hash of a variable. I have specialized its template to int, double and std::string like this

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;
    }
};

I then created a generic version of the same method which takes a template parameter and tries to convert it to std::string and then tries to call operator() on it (which I'd expect would call the specialized template one)

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);
    }

(it's inside the class declaration while the other 3 are in a different file)
So when I call operator() of the Hash class on a int, double or std::string it works fine, but the moment I try to call it on a different class of mine i get this error:

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>}

So it seems to me that it's trying to call operator(BST) again, even though i've passed a string to it. Is there a way I can solve this? I don't care about the hash function being incorrect, I have a uni assignment to do it this way, I only need to understand if it is even possible to call a specialized template function from a normal template one.
I also tried using

return operator()<std::string>(s);

as I've seen in some other answers of a similiar question, but I get the following error:

error: expected primary-expression before ‘>’ token
   35 |                         return operator()<std::string>(s);
      |                                                      ^

https://gcc.godbolt.org/z/9oz8Gf9aM

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

美人如玉 2025-02-09 17:59:11

如果我正确理解,您的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);
  
}

Update update

更新后的帖子/错误消息,您正在使用Perface hash&lt; std :: String&gt; 在声明并定义之前。那就是在线:

return Hash<std::string>{}(s);

编译器不知道hash std :: String的专业化。因此,错误!

(一种方法)要解决它,您需要将声明和定义分开如下:

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);
}

请参阅演示

If I understood correctly, your operator() needs a Hash instance to call its specialized operator()

auto operator()(const Data& d) const noexcept
{
    // ....
    std::string s = "";
    return Hash<std::string>{}.operator()(s);
    //     ^^^^^^^^^^^^^^^^^^^ 
    // OR simply
    // return Hash<std::string>{}(s);
  
}

Update

From the updated post/ error message, you are using the specialization Hash<std::string> before it has been declared as well as defined. That is at the line:

return Hash<std::string>{}(s);

compiler does not know about the Hash specialization for std::string. Hence, the error!

(One way) to fix it, you need to split the declaration and the definition as follows:

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);
}

See a demo

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文