簡體   English   中英

基於后面模板類型的默認模板類型

[英]Default template type based on later template type

我有一個 function ,它創建一個 object 並將其插入容器中。 在大多數情況下,object 類型與容器元素的類型相同。 然后,我不想指定 object 類型。 但是對於持有std::variant的容器,我希望能夠將 object 類型指定為第一個模板參數。 這是非工作示例:

template<typename T>
using remove_qualifiers = std::remove_cv_t<std::remove_reference_t<T>>;
template<typename T>
using IteratorType = decltype( std::declval<remove_qualifiers<T>>().end() );
template<typename T>
using ElementType = decltype( *( std::declval<remove_qualifiers<T>>().end() ) );

template<typename E = ElementType<T>, typename T, typename ... Args>
IteratorType<T> insert( T& someContainer, Args&& ... ){
    IteratorType<T> it { someFindFunc() };
    return someContainer.insert(it, E{std::forward<Args>(args) ...});
}

問題是, E的默認類型基於T ,此時尚未聲明。 但是如果我更改順序,那么調用 function 就會變得很尷尬。

如何使這種模式起作用,以便我可以在指定和不指定E的情況下調用 function ?

我想這可能是沒有找到正確的搜索詞的情況。 我看了這個這個這個這個,它們似乎不是我要找的。

考慮將其包裝到 class 模板中,這樣您就不必擔心指定容器的類型。

template <typename T>
class Inserter {
public:
    Inserter(T& someContainer): container{someContainer} {}
    using IteratorType = decltype( std::declval<remove_qualifiers<T>>().end() );

    template <typename E = ElementType<T>, typename... Args>
    IteratorType insert(Args&&... args) {
        IteratorType it = container.begin(); // just for sample
        return container.insert(it, E{std::forward<Args>(args) ...});
    }
private:
    T& container;
};

然后,

std::vector<std::variant<int, double>> v;
Inserter{v}.insert<int>(1);
Inserter{v}.insert<double>(1.1);

演示

如果您不使用某種 emplace,則應該將構造移至調用者。 為簡單起見,我使用push_back而不是insert

template <typename T, typename Value>
inline auto insert(T& container, Value&& value) {
  container.push_back(std::forward<Value>(value));
}

但是讓我們假設您確實在適當地構造類型。

template <typename T, typename... Args>
inline auto emplace(T& container, Args&&... args) {
  container.emplace_back(std::forward<Args>(args)...);
}

這可能就是您所需要的。 您也可以構造任何類型、變體。

struct A {  int n; };
struct B {  int n; };

auto a = std::vector<A>{};
emplace(a, 100);

auto b = std::vector<B>{};
emplace(b, 100);

auto ab = std::vector<std::variant<A, B>>{};
emplace(ab, std::in_place_type_t<A>{}, 100); // tell the type
emplace(ab, 100); // ambigious, compile error

至於您的特定用例,無法推斷出某種默認類型的變體。 你總是必須明確地告訴你要構造什么。

您可以重新發明輪子,為變體創建重載,然后隱藏std::in_place_type_t 但通常這個問題已經被 STL 解決了,對於任何可以就地構建的類型。

暫無
暫無

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

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