簡體   English   中英

選擇專用於派生實例的基類的類模板

[英]Select class template specialised for base-class of derived instance

請考慮以下示例程序:

#include <iostream>

template<typename T>
struct Dispatch
{
    static void send(T&) { std::cout << "unknown\n"; }
};

struct Processor
{
    template<typename T>
    void process(T&& t) { Dispatch<T>::send(t); }
};

template<typename T>
struct Base
{};

template<typename T>
struct Dispatch<Base<T>>
{
    static void send(Base<T>&) { std::cout << "base\n"; }
};

struct Deriv : Base<int>
{};

int main()
{
    Processor p;
    p.process(Base<int>{}); // prints "base"
    p.process(Deriv{});     // prints "unknown"
    return 0;
}

當使用Deriv實例(它是Base子類)調用Processor::process()時,我希望選擇專門用於Base類模板的Dispatcher()

但是,在上面的示例中,會發生以下情況:

  • Base<T>實例傳遞給process()調用Base<T>
  • Deriv實例傳遞給process()調用主類模板

題:

  • 為什么Base<T>不是Deriv比主類模板更好的專業化?
  • 有沒有打電話給一般的方式Base<T>時,通過專業化Base<T>的子類?

使用SFINAE,您可以:

// Traits to detect inheritance:
template <typename T> std::true_type derive_from_base_impl(Base<T>*);
std::false_type derive_from_base_impl(...);

template <typename T>
using derive_from_base_t = decltype(derive_from_base_impl(std::declval<T*>()));

然后一些變化

template<typename T, typename Enabler = void>
struct Dispatch
{
    static void send(T&) { std::cout << "unknown\n"; }
};

template<typename T>
struct Dispatch<T, std::enable_if_t<derive_from_base_t<T>::value>>
{
    static void send(T&) { std::cout << "base\n"; }
};

演示

模板專業化適用於字面上相同的類型。 如果您使用Base專用模板,則此專業化將不適用於Derived

解決此問題的一種方法是使用部分特化,您可以為從Base派生的類型啟用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM