use*_*886 4 c++ templates class function-templates c++17
这个问题继续 非静态数据成员类推导
这是未命名的参数函数,我用它来返回std::string数据类型的表示
struct Boo {};
struct Foo {};
std::string class2str(const double) { return "Floating"; };
std::string class2str(const int) { return "Fixed Point"; };
std::string class2str(const Foo) { return "Class Foo"; };
std::string class2str(const Boo) { return "Class Boo"; };
int main(int argc, char* argv[])
{
int x_a;
double x_b;
Foo F;
Boo B;
std::cout << "x_a :" << class2str(x_a) << std::endl;
std::cout << "x_b :" << class2str(x_b) << std::endl;
std::cout << "Foo :" << class2str(F) << std::endl;
std::cout << "Boo :" << class2str(B) << std::endl;
};
Run Code Online (Sandbox Code Playgroud)
对于非静态成员的类型推导,我使用模板:
struct Foo { double A = 33; }
template<typename Class, typename MemType>
std::string class2str(MemType Class::* mData)
{
return class2str(MemType{}); // Use of empty constructor
}
std::cout << "Foo::A :" << class2str(&Foo::A) << std::endl;
Run Code Online (Sandbox Code Playgroud)
但是这个模板需要创建一个带有空构造函数的对象,它可能根本不存在
struct Boo
{
double A;
Boo() = delete;
Boo(int x) :A(x) {};
};
struct Foo
{
double A = 33;
Boo b{ 0 };
};
// Compilation error: use of deleted function ‘Boo::Boo()’
std::cout << "Boo::b :" << class2str(&Foo::b) << std::endl;
Run Code Online (Sandbox Code Playgroud)
如何实现此功能,但不调用空构造函数?
看在线演示:https : //onlinegdb.com/lpc5o8pUKy
(当我开始写答案时,这个问题没有答案,但是当我准备发布它时,我看到 @Jarod42 的答案已经显示了标签调度方法。尽管如此,发布这个答案,因为它使用了完全专业化的稍微不同的方法删除的主模板,而不是非模板重载)
您可以使用标签调度来委托调用:
#include <iostream>
struct Boo {
double A;
Boo() = delete;
Boo(int x) : A(x){};
};
struct Foo {
double A = 33;
Boo b{0};
};
namespace detail {
template <typename T> struct Tag {};
template <typename T> std::string class2str_impl(Tag<T>) = delete;
template <> std::string class2str_impl(Tag<double>) { return "Floating"; };
template <> std::string class2str_impl(Tag<int>) { return "Fixed Point"; };
template <> std::string class2str_impl(Tag<Foo>) { return "Class Foo"; };
template <> std::string class2str_impl(Tag<Boo>) { return "Class Boo"; };
} // namespace detail
template <typename T> std::string class2str(T) {
return class2str_impl(detail::Tag<T>{});
}
template <typename Class, typename MemType>
std::string class2str(MemType Class::*) {
return class2str_impl(detail::Tag<MemType>{});
}
int main() {
int x_a{42};
double x_b{4.2};
Foo F{};
Boo B{x_a};
std::cout << "x_a :" << class2str(x_a) << std::endl;
std::cout << "x_b :" << class2str(x_b) << std::endl;
std::cout << "Foo :" << class2str(F) << std::endl;
std::cout << "Boo :" << class2str(B) << std::endl;
std::cout << "Boo::b :" << class2str(&Foo::b) << std::endl;
};
Run Code Online (Sandbox Code Playgroud)
其中的主模板class2str_impl可以被删除(如上所述),或者实现给定类型没有映射字符串的自定义消息。
| 归档时间: |
|
| 查看次数: |
128 次 |
| 最近记录: |