c ++模板成员函数,根据模板参数更改参数

时间:2018-03-23 18:12:33

标签: c++ templates

---编辑更多背景---

假设我有一个名为TempClass的类。顾名思义就是它的模板类。它有很多东西对这个问题并不重要,但有趣的东西是一个名为addTo的成员函数和一个unordered_map对象的成员变量。让我们称之为insertedinserted中的所有内容都使用addTo放入其中。 addTo应该做的是使一些对象随后插入到给定键的集合中。插入的实例应该在函数内部创建,而不是传递给它。

addTo(KeyType key, ...) // im looking for what I should put at ...

基本上我在关键后被困在一切。我需要一种方法可以为新创建的实例指定数据,而不必担心对象的生命周期,或者通过调用std :: make_xxx(共享,唯一等)来复杂化。

以下是我希望它被称为

的方式
TempClass<std::string> stringClass();
stringClass.addTo(whereToAddIt, "This was selected because of std::string");
TempClass<Vector3f> vectorClass();
vectorClass.addTo(someOtherLocation, 12.0f,12.0f,3.0f); //adds a vec(12.0f,12.0f,3.0f)

我已经看到过这样做了,如果这是一般的好习惯,那就爱这样实现它。

我尝试过:

  • 将指针传递给函数 ------&GT;工作,但是很愚蠢。它要求我注意删除对象
  • 在插入之前传递临时对象并复制它 ------&GT;但我不喜欢复制对象只是为了删除它。它似乎是冗余的,并不适合我的特定应用。

我之前已经看过这件事,但我不记得在哪里(相信我,我曾试图记住这一点,因为如果可以,我可以自己查一下)。请详细解释如何执行此操作及其工作原理。

请帮我解决这个问题!

2 个答案:

答案 0 :(得分:1)

您可以使用重载,然后在模板类型为特定类型时启用某个重载

#include <type_traits> //for enable_if and is_same

template<typename T>
class MyClass
{
public:
    template<typename = std::enable_if<std::is_same_v<T, std::string>>>
    void someMember(string param1, int param2);
    template<typename = std::enable_if<std::is_same_v<T, Vector3f>>>
    void someMember(string param1, int param2, int param3);
};

这将选择第一个重载是T是std:string,如果T是Vector3f则选择第二个重载。

编辑:查看您编辑过的问题,更好的方法是将T的实例传递给addTo函数。像:

void addTo(std::string key, T const& value);

EDIT2:我想我终于知道你真正想要的了。您需要使用可变参数模板并完美转发。这可能看起来令人困惑,所以我会给你代码:

template<typename KeyType, typename... Args>
void addTo(KeyType key, Args&&... args)
{
   //now construct the new element with:
   T elem(std::forward<Args>(args)...);
}

您需要包含实用程序标头。有关可变参数模板的更多信息,请参阅cppreference

答案 1 :(得分:1)

您可以使用可变参数模板和完美转发来放置k / v对:

template<class K, class V>
struct foo {
    template<class... Args>
    void addTo(K k, Args&&... args) {
        mp.emplace(
                std::piecewise_construct, 
                std::forward_as_tuple(k),
                std::forward_as_tuple(std::forward<Args>(args)...)
                );
    }
    std::unordered_map<K, V> mp;
};