这是另一种不使用标签调度的解决方案。在这里,构造函数按选定的顺序进行测试,并且可以使用带有可变参数模板的简单构造函数,而无需从接口可变参数模板构造函数完美转发。例如。我可以使用带有 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