代码嵌入技巧

代码嵌入技巧

修改类模板成员实现

#include <iostream>

template <typename T>
class A
{
public:
void Speak()
{
std::cout << "A" << '\n';
}
};

template <> void A<int>::Speak()
{
std::cout << "Int" << '\n';
}

int main()
{
A<int> a;
a.Speak();
return 0;
}

删除类模板实现

#include <iostream>

template <typename T>
class A
{
public:
void Speak()
{
std::cout << "A" << '\n';
}
};

template <> void A<int>::Speak() = delete;

int main()
{
A<int> a;
a.Speak();
return 0;
}

嵌入成员函数

背景:

#include <iostream>
#include <type_traits>
#include <string>

class MoveMsg
{
public:
MoveMsg(int, int) {}
void speak()
{
std::cout << "Move" << '\n';
}
};

class SleepMsg
{
public:
SleepMsg(std::string) {}
void speak()
{
std::cout << "Sleep" << '\n';
}
};

class ExitMsg
{
public:
void speak()
{
std::cout << "Exit" << '\n';
}
};

1. 嵌入已有成员函数

​ 利用模板代替继承。

#include <iostream>
#include <type_traits>
#include <string>

class MoveMsg
{
public:
MoveMsg(int, int) {}
void speak()
{
std::cout << "Move" << '\n';
}
};

class SleepMsg
{
public:
SleepMsg(std::string) {}
void speak()
{
std::cout << "Sleep" << '\n';
}
};

class ExitMsg
{
public:
void speak()
{
std::cout << "Exit" << '\n';
}
};

template <typename Msg>
class MsgImpl {
Msg msg;
public:
template<typename... Args>
MsgImpl(Args&&...args) : msg(std::forward<Args>(args)...) {}
void speak()
{
msg.speak();
}

MsgImpl(Msg&& msg) : msg(std::forward<Msg>(msg)) {}
};

int main()
{
MsgImpl<MoveMsg> mmsg(1, 2);
MsgImpl<SleepMsg> smsg("Hello");
MsgImpl<ExitMsg> emsg();
return 0;
}

2. 部分成员函数不存在,保证一致性嵌入

​ 利用C++20的requires特性。

#include <iostream>
#include <type_traits>
#include <string>

class MoveMsg
{
public:
MoveMsg(int, int) {}
void speak()
{
std::cout << "Move" << '\n';
}

void hello()
{
std::cout << "Move hello" << '\n';
}
};

class SleepMsg
{
public:
SleepMsg(std::string) {}
void speak()
{
std::cout << "Sleep" << '\n';
}
void hello()
{
std::cout << "Sleep hello" << '\n';
}
};

class ExitMsg
{
public:
void speak()
{
std::cout << "Exit" << '\n';
}
};

template <typename Msg>
class MsgImpl {
Msg msg;
public:
template<typename... Args>
MsgImpl(Args&&...args) : msg(std::forward<Args>(args)...) {}
void speak()
{
msg.speak();
}

void hello()
{
if constexpr(requires{msg.hello()})
{
msg.hello();
}
else
{
std::cout << "not exists" << '\n';
}
}

MsgImpl(Msg&& msg) : msg(std::forward<Msg>(msg)) {}
};

int main()
{
MsgImpl<MoveMsg> mmsg(1, 2);
MsgImpl<SleepMsg> smsg("Hello");
MsgImpl<ExitMsg> emsg();
return 0;
}

3. 成员函数都不存在,需要额外嵌入

#include <iostream>
#include <type_traits>
#include <string>

class MoveMsg
{
public:
MoveMsg(int, int) {}
void speak()
{
std::cout << "Move" << '\n';
}
};

class SleepMsg
{
public:
SleepMsg(std::string) {}
void speak()
{
std::cout << "Sleep" << '\n';
}
};

class ExitMsg
{
public:
void speak()
{
std::cout << "Exit" << '\n';
}
};

namespace Msg_Extra
{
template <typename Msg>
void hello(Msg &msg) {}

void hello(MoveMsg& msg)
{
std::cout << "Move hello" << '\n';
}

void hello(SleepMsg& msg)
{
std::cout << "Sleep hello" << '\n';
}
}

template <typename Msg>
class MsgImpl {
Msg msg;
public:
template<typename... Args>
MsgImpl(Args&&...args) : msg(std::forward<Args>(args)...) {}
void speak()
{
msg.speak();
}

void hello()
{
Msg_Extra::hello(msg);
}

MsgImpl(Msg&& msg) : msg(std::forward<Msg>(msg)) {}
};

int main()
{
MsgImpl<MoveMsg> mmsg(1, 2);
MsgImpl<SleepMsg> smsg("Hello");
MsgImpl<ExitMsg> emsg();
return 0;
}