You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将第三方库模板类实例传入自定义类构造函数?

Hey there! Let's work through how to pass an instance of that third-party template class into your custom library class. I’ve got a few practical approaches that should fit different scenarios, depending on what you need:

1. Make Your Custom Class a Template Too

This is the most straightforward approach if you don’t mind your custom class being templated. It lets you directly accept the third-party template instance while preserving full type information.

Here’s a code example to illustrate:

// Third-party template class (example structure)
template <typename T>
class ThirdPartyTemplate {
public:
    void doSomething(T value) {
        // Third-party implementation here
    }
};

// Your custom class, now templated to match the third-party class
template <typename T>
class MyCustomClass {
private:
    ThirdPartyTemplate<T>& tp_instance; // Use reference if you manage the instance's lifetime
    // Or use a pointer: ThirdPartyTemplate<T>* tp_instance;

public:
    // Constructor takes a reference to the third-party instance
    MyCustomClass(ThirdPartyTemplate<T>& instance) : tp_instance(instance) {}

    void useThirdPartyFeature() {
        // Call methods on the third-party instance directly
        tp_instance.doSomething(42);
    }
};

// Usage example
int main() {
    ThirdPartyTemplate<int> tp_int_instance;
    MyCustomClass<int> my_class(tp_int_instance);
    my_class.useThirdPartyFeature();

    return 0;
}

Pros: No runtime overhead, full access to the third-party class’s methods, and minimal code changes.
Cons: Your custom class will generate separate instantiations for each T you use, which could increase compile time and binary size if you have many different types.

2. Use Type Erasure for Flexibility

If you want your custom class to work with any instantiation of the third-party template (without being templated itself), type erasure is a great option. This involves wrapping the third-party instance in an adapter that implements a common interface.

Check out this implementation:

#include <memory>

// Define an abstract interface with the methods you need from the third-party class
class ThirdPartyInterface {
public:
    virtual ~ThirdPartyInterface() = default;
    virtual void performGenericAction() = 0; // Adjust to match your required methods
};

// Template adapter that wraps the third-party instance and implements the interface
template <typename T>
class ThirdPartyAdapter : public ThirdPartyInterface {
private:
    ThirdPartyTemplate<T>& tp_instance;

public:
    ThirdPartyAdapter(ThirdPartyTemplate<T>& instance) : tp_instance(instance) {}

    void performGenericAction() override {
        // Map the interface method to the third-party class's method
        tp_instance.doSomething(42);
    }
};

// Your custom class, now dependent only on the abstract interface
class MyCustomClass {
private:
    std::unique_ptr<ThirdPartyInterface> interface_ptr;

public:
    // Template constructor to accept any third-party template instance
    template <typename T>
    MyCustomClass(ThirdPartyTemplate<T>& instance) {
        interface_ptr = std::make_unique<ThirdPartyAdapter<T>>(instance);
    }

    void useThirdParty() {
        interface_ptr->performGenericAction();
    }
};

// Usage example
int main() {
    ThirdPartyTemplate<int> tp_int_instance;
    MyCustomClass my_class1(tp_int_instance);
    my_class1.useThirdParty();

    ThirdPartyTemplate<std::string> tp_str_instance;
    MyCustomClass my_class2(tp_str_instance);
    my_class2.useThirdParty();

    return 0;
}

Pros: Your custom class stays non-templated, works with any instantiation of the third-party template, and keeps your code decoupled from the third-party implementation.
Cons: Small runtime overhead from virtual function calls, and you can only call methods defined in the abstract interface (you’ll need to extend the interface if you need more functionality).

3. Target Specific Template Instantiations

If you only need to support a fixed set of third-party template instantiations (e.g., ThirdPartyTemplate<int>, ThirdPartyTemplate<std::string>), you can use overloaded constructors or std::variant to handle them directly.

Here’s how to do it with std::variant:

#include <variant>

// Third-party template class
template <typename T>
class ThirdPartyTemplate {
public:
    void doSomething(T value) { /* ... */ }
};

// Your custom class
class MyCustomClass {
private:
    std::variant<ThirdPartyTemplate<int>&, ThirdPartyTemplate<std::string>&> tp_variant;

public:
    // Overloaded constructors for each supported type
    MyCustomClass(ThirdPartyTemplate<int>& instance) : tp_variant(instance) {}
    MyCustomClass(ThirdPartyTemplate<std::string>& instance) : tp_variant(instance) {}

    void useThirdParty() {
        // Use std::visit to handle each type case
        std::visit([](auto& instance) {
            instance.doSomething(42); // Works if all supported types have this method
        }, tp_variant);
    }
};

Pros: No runtime overhead from virtual functions, type-safe, and your custom class remains non-templated.
Cons: Inflexible—you’ll need to modify the class every time you want to support a new template instantiation.

Final Recommendation

  • Go with approach 1 if you need full access to the third-party class and don’t mind your custom class being templated.
  • Use approach 2 if you need maximum flexibility and want to decouple your code from the third-party template.
  • Choose approach 3 if you only need to support a small, fixed set of third-party instantiations.

内容的提问来源于stack exchange,提问作者LeSinge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:39:33