簡體   English   中英

函數調用優先級的重載和模板專門化

[英]Overloading and template specialization for function call priority

參考以下代碼:

我試圖有條件地編譯一堆函數,然后使用prioirty_tag class對它們進行“排序”。 我的問題是,如果我替換enable_if_t<is_nothrow_move_constructible<U>{}>* = nullptr>enable_if_t<is_nothrow_move_constructible<U>{}>>輸出不正確(默認為第一功能)。

那里到底發生了什么? 為什么添加* = nullptr使其起作用?

#include <iostream>
#include <type_traits>

using namespace std;

template <size_t T>
struct priority_tag: priority_tag<T-1> {};
template <>
struct priority_tag<0> {};

template <typename T>
struct my_vec
{   
        template <typename U = T, typename = void>
        void realloc_impl(priority_tag<0> pr)
        {
            cout << "Move throw construct\n";
        };

        //template <typename U = T, enable_if_t<is_copy_constructible<U>{}>> this wont work!

        template <typename U = T, enable_if_t<is_copy_constructible<U>{}>* = nullptr>
        void realloc_impl(priority_tag<1> pr)
        {
            cout << "copy construct \n";
        };

        //template <typename U = T, enable_if_t<is_copy_constructible<U>{}>> this wont work!

        template <typename U = T, enable_if_t<is_nothrow_move_constructible<U>{}>* = nullptr>
            void realloc_impl(priority_tag<2> pr)
        {
            cout << "nothrow move \n";
        };
        void realloc()
        {
                priority_tag<2> pr;
                realloc_impl(pr);
        }

        const static int val = is_nothrow_move_constructible<T>{} ? 1 : is_copy_constructible<T>{} ? 2 : 3;

        priority_tag<val> g;

};

class A {
public:
    A() = default;
    A(A&&) noexcept = default;
};

class B {
public:
    B() = default;
    B(B&&) = delete;
    B(const B&) = default;
};

class C {
public:
    C() = default;
    C(C&&) {}
    C(const C&) = delete;
};


int main()
{
        my_vec<A> obj;
        obj.realloc();

        cout << obj.val;
}

嘗試編譯以下代碼

template<void>
void foo(){}

我得到了編譯器錯誤'void',它不是模板非類型參數的有效類型


作為模板參數,您可以傳遞:

1) 輸入,然后使用class / typename聲明它,如下所示:

template< class/typename A[optional] = void>
void foo2(){}

2) 非類型,則可以傳遞一些整數值,指針,左值引用等作為模板參數( 此處為完整列表)

template<void*>
void foo3(){}

3)模板類型參數

在您的示例中, is_nothrow_move_constructibleA返回true,然后編譯器遇到以下行:

template <typename U = T, enable_if_t<is_nothrow_move_constructible<U>{}>>

什么是:

template <typename U = T, void>

此行的語法錯誤,並且編譯器從重載集中刪除了該成員函數模板。 您可以通過聲明enable_if_t<is_nothrow_move_constructible<U>{}作為類型參數來修復它:

template <typename U = T, 
          typename   = enable_if_t<is_nothrow_move_constructible<U>{}> > // typename = void
    void realloc_impl(priority_tag<2> pr)
    {
        cout << "nothrow move \n";
    };

或作為非類型(指向void的指針),即您在示例中所做的。

暫無
暫無

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

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