带有方法参数的元编程
Meta-Programming with a Method Parameter
我正在编写一个 pair
包装器。出于这个问题的目的,它可以简化为:
using namespace std;
template <class T1, class T2>
class myPair {
pair<T1, T2> member;
public:
myPair() = default;
myPair(T1 x, T2 y) : member(make_pair(x, y)) {}
};
我希望能够将 myPair
视为大小为 2 的可索引容器。为此,我显然需要为 myPair
编写一个索引运算符。我想做这样的事情,但是我的 return 类型将取决于方法参数,我不能在元编程中使用方法参数。
auto myPair::operator[](int index) {
static_assert(index >= 0 && index < 2, "Index out of range");
return get<index>(*this);
}
显然我可以通过提供 get
函数以与 pair
相同的方式解决这个问题,但我希望能够使用索引运算符语法。有什么方法可以专门化函数模板或使用方法参数对模板的 return 类型进行元编程?
不,这不可能。成员函数 operator[]
接受非 constexpr 对象,因此几乎不可能进行编译时类型检测。
出于同样的原因,这也会使 static_assert
无法编译。
几乎可能。整型文字不能直接用作常量表达式,但可以包装在一个,例如模板实例化中。
template <int> struct idx_ {};
template <char... C>
auto operator ""_i () {
return idx_<(C - '0')...>{};
}
template <class T1, class T2>
class myPair {
std::pair<T1, T2> member;
public:
myPair() = default;
myPair(T1 x, T2 y) : member(std::make_pair(x, y)) {}
T1 &operator [] (idx_<0>) {
return member.first;
}
T2 &operator [] (idx_<1>) {
return member.second;
}
};
int main() {
myPair<int, std::string> mp(42, "Hi");
std::cout << mp[0_i] << ", " << mp[1_i] << '\n';
}
输出:
42, Hi
您可以使用 std::intergral_constant
template <std::size_t N>
const auto& operator[](std::integral_constant<std::size_t, N>) const {
static_assert(N < 2, "Index out of range");
return std::get<N>(member);
}
template <std::size_t N>
auto& operator[](std::integral_constant<std::size_t, N>) {
static_assert(N < 2, "Index out of range");
return std::get<N>(member);
}
我正在编写一个 pair
包装器。出于这个问题的目的,它可以简化为:
using namespace std;
template <class T1, class T2>
class myPair {
pair<T1, T2> member;
public:
myPair() = default;
myPair(T1 x, T2 y) : member(make_pair(x, y)) {}
};
我希望能够将 myPair
视为大小为 2 的可索引容器。为此,我显然需要为 myPair
编写一个索引运算符。我想做这样的事情,但是我的 return 类型将取决于方法参数,我不能在元编程中使用方法参数。
auto myPair::operator[](int index) {
static_assert(index >= 0 && index < 2, "Index out of range");
return get<index>(*this);
}
显然我可以通过提供 get
函数以与 pair
相同的方式解决这个问题,但我希望能够使用索引运算符语法。有什么方法可以专门化函数模板或使用方法参数对模板的 return 类型进行元编程?
不,这不可能。成员函数 operator[]
接受非 constexpr 对象,因此几乎不可能进行编译时类型检测。
出于同样的原因,这也会使 static_assert
无法编译。
几乎可能。整型文字不能直接用作常量表达式,但可以包装在一个,例如模板实例化中。
template <int> struct idx_ {};
template <char... C>
auto operator ""_i () {
return idx_<(C - '0')...>{};
}
template <class T1, class T2>
class myPair {
std::pair<T1, T2> member;
public:
myPair() = default;
myPair(T1 x, T2 y) : member(std::make_pair(x, y)) {}
T1 &operator [] (idx_<0>) {
return member.first;
}
T2 &operator [] (idx_<1>) {
return member.second;
}
};
int main() {
myPair<int, std::string> mp(42, "Hi");
std::cout << mp[0_i] << ", " << mp[1_i] << '\n';
}
输出:
42, Hi
您可以使用 std::intergral_constant
template <std::size_t N>
const auto& operator[](std::integral_constant<std::size_t, N>) const {
static_assert(N < 2, "Index out of range");
return std::get<N>(member);
}
template <std::size_t N>
auto& operator[](std::integral_constant<std::size_t, N>) {
static_assert(N < 2, "Index out of range");
return std::get<N>(member);
}