这是另一个不使用标签分派的解决方案。这里的构造函数按照选定的顺序进行测试,并且可以使用简单的构造函数和可变参数模板构造函数,但没有从界面可变模板构造函数完美转发。例如。我可以使用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呢?它不被使用,这是故意的吗? –