這是另一個不使用標籤分派的解決方案。這裏的構造函數按照選定的順序進行測試,並且可以使用簡單的構造函數和可變參數模板構造函數,但沒有從界面可變模板構造函數完美轉發。例如。我可以使用std :: pair參數的構造函數,並在其中使用括號初始值設定項列表{ "String", 6 }
,而不是明確地通過std::pair<char const*, size_t>("String", 6)
等等,如示例所示。該方法不僅可以用來控制構造函數的優先級,還可以用來控制其他成員的重載優先級。目前它需要一個幫手類。
我是新的不同的元編程技巧,它只是一個建議。我不會改進它。
#include <type_traits>
#include <cstddef>
#include <iostream>
using namespace std;
一些標準樣類:
struct null_helper { static constexpr int const value = 0; };
template<template<unsigned> typename Helper, unsigned order, typename ...TT>
class constructible_from_order
{
using PrevType = typename conditional<(order < 1), null_helper,
constructible_from_order<Helper, order-1, TT&&...>>::type;
static constexpr int const prev = PrevType::value;
static constexpr bool const is_this_constructible = is_constructible<Helper<order>, TT&&...>::value;
public:
static constexpr int const value = prev ? prev : is_this_constructible ? order : 0;
}; // template class constructible_from_order
template<template<unsigned> typename Helper, unsigned order, typename ...TT>
using enable_in_order = enable_if<(constructible_from_order<Helper, order, TT&&...>::value == order)>;
template<template<unsigned> typename Helper, unsigned order, typename ...TT>
using enable_in_order_t = typename enable_in_order<Helper, order, TT&&...>::type;
例如類定義:
using blob_data = pair<char const*, size_t>;
class C {
template<unsigned order>
class helper
{
public:
helper(char const*, size_t) {} // 1
helper(blob_data const&, blob_data const&) {} // 1
template<typename T, typename = enable_if_t<(order == 2) && sizeof(T)>>
helper(blob_data const&, T&&) {} // 2
template<typename T, typename = enable_if_t<(order == 3) && sizeof(T)>>
helper(T&&, blob_data const&) {} // 3
template <class... Ts, typename = enable_if_t<(order == 4) && sizeof...(Ts)>>
helper(Ts&&...) {} // 4
}; // template class helper
public: // constructors:
// order 1
C(char const*, size_t) { cout << "1" << endl; }
// order 1
C(blob_data const&, blob_data const&) { cout << "1" << endl; }
// order 2
template<typename T, typename = enable_in_order_t<helper, 2, blob_data const&, T&&>>
C(blob_data const&, T&&) { cout << "2" << endl; }
// order 3
template<typename T, typename = enable_in_order_t<helper, 3, T&&, blob_data const&>>
C(T&&, blob_data const&) { cout << "3" << endl; }
// order 4
template <class... Ts, typename = enable_in_order_t<helper, 4, Ts&&... >>
C(Ts&&...) { cout << "4" << endl;}
public: // member functions:
// order 1
void fun(char const*, size_t) { cout << "1" << endl; }
// order 1
void fun(blob_data const&, blob_data const&) { cout << "1" << endl; }
// order 2
template<typename T, typename = enable_in_order_t<helper, 2, blob_data const&, T&&>>
void fun(blob_data const&, T&&) { cout << "2" << endl; }
// order 3
template<typename T, typename = enable_in_order_t<helper, 3, T&&, blob_data const&>>
void fun(T&&, blob_data const&) { cout << "3" << endl; }
// order 4
template <class... Ts, typename = enable_in_order_t<helper, 4, Ts&&... >>
void fun(Ts&&...) { cout << "4" << endl;}
}; // class C
用作:
int main() {
char const* str = "aaa";
// constructors:
cout << "Constructors: " << endl;
cout << "1: "; C c1 { str, size_t{5} };
cout << "1: "; C cx { { str, 5 }, { str, 5 } };
cout << "2: "; C c2 { { str, 5 }, str };
cout << "3: "; C c3 { str, { str, 5 } };
cout << "4: "; C c4 { str, str };
cout << endl;
// functions:
cout << "Functions: " << endl;
cout << "1: "; c1.fun( str, size_t{5});
cout << "1: "; c1.fun({ str, 5 }, { str, 5 });
cout << "2: "; c1.fun({ str, 5 }, str);
cout << "3: "; c1.fun( str, { str, 5 });
cout << "4: "; c1.fun( str, str);
cout << endl;
} // main
程序輸出:
Constructors:
1: 1
1: 1
2: 2
3: 3
4: 4
Functions:
1: 1
1: 1
2: 2
3: 3
4: 4
您希望保持可變模板和非模板構造函數,並確保它首先調用非模板構造函數;它是否正確? –
@ Lorenzo Belli是的 –
U呢?它不被使用,這是故意的嗎? –