静态类特征的条件执行路径
在尝试实现现有 API 的新 API 替代方案时,我无法找到适当的解决方案,但我仍然希望支持向后兼容性;
让这是我的旧API:
typedef int[3] Node;
template <class T>
struct convert{
static std::pair<bool, T> decode(Node node);
}
//and a call to this construct here
template<typename T>
T decode_for_me(Node node) {
return convert<T>::decode(node).second;
}
//with a specialization, for example a custom type
struct custom_type {int a; int b;};
template<>
struct convert<custom_type>{
static std::pair<bool, custom_type> decode(Node node) {
custom_type c; c.a=node[0]; c.b=node[1]; return std::make_pair(true, c); };
};
int main() {
Node node = {1,2};
decode_for_me<custom_type>(node);
return 0;
}
现在想将convert::decode更改为更精简的签名并刷新API以实现更多类型:
class alt_type {
int x; int y; int z;
alt_type(int x, int y, int z) : x(x), y(y), z(z) {};
}
template<>
struct convert<alt_type>{
static alt_type decode_new_api(Node node) {return {node[0], node[1], node[2]};};
}
我现在将如何在类布局上实现条件切换/trait of convert
选择正确的调用路径,将 decode_for_me
替换为:
template<typename T>
T decode_for_me(Node node) {
if constexpr ( "has_trait<convert<T>, "decode">" ) //<<<<
return convert<T>::decode(node).second;
if constexpr ( "has_trait<convert<T>, "decode_new_api">" ) // <<<<
return convert<T>::decode_new_api(node);
throw std::runtime_error();
}
我研究了一些类似的问题和答案来处理这个问题SFINAE 与使用 decltype
和 declval
的模板构造不同。然而,所有这些都涉及成员函数,而在这里我对静态评估感兴趣。而且我也无法让他们中的任何人为我工作。
感谢您的帮助!
I have problems finding an adequate solution in the attempt to implement an new API alternative to an existing API, which I still want to support for backwards-compatibility;
let this be my old API:
typedef int[3] Node;
template <class T>
struct convert{
static std::pair<bool, T> decode(Node node);
}
//and a call to this construct here
template<typename T>
T decode_for_me(Node node) {
return convert<T>::decode(node).second;
}
//with a specialization, for example a custom type
struct custom_type {int a; int b;};
template<>
struct convert<custom_type>{
static std::pair<bool, custom_type> decode(Node node) {
custom_type c; c.a=node[0]; c.b=node[1]; return std::make_pair(true, c); };
};
int main() {
Node node = {1,2};
decode_for_me<custom_type>(node);
return 0;
}
now is would like to change a convert::decode to a little bit more slim signature and refresh the API for further types implemented:
class alt_type {
int x; int y; int z;
alt_type(int x, int y, int z) : x(x), y(y), z(z) {};
}
template<>
struct convert<alt_type>{
static alt_type decode_new_api(Node node) {return {node[0], node[1], node[2]};};
}
how would i now go about to implement a conditional switch on the class-layout/trait of convert<T>
to select the correct call-path, replacing decode_for_me<T>()
as:
template<typename T>
T decode_for_me(Node node) {
if constexpr ( "has_trait<convert<T>, "decode">" ) //<<<<
return convert<T>::decode(node).second;
if constexpr ( "has_trait<convert<T>, "decode_new_api">" ) // <<<<
return convert<T>::decode_new_api(node);
throw std::runtime_error();
}
I researched some similar questions and answers dealing with this in SFINAE varying from template constructs over use of decltype
and declval
. However, all those deal with member functions, while here I am interested in static evaluation. Also I could get none of them to work for me.
Thanks for any help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不知道如何使用接收方法名称(decode 或decode_new_api)作为参数的单一类型特征来解决此问题。
但是,如果您接受对不同方法的不同测试,一个可能的解决方案是使用几个已声明(无需定义)的函数来测试“declare”
和几个用于“declare_new_api”的
函数。现在您的
decode_for_me()
变得I don't know a way to solve this problem with a single type-traits that receive the name of the method (decode or decode_new_api) as argument.
But, if you accept different tests for different methods, a possible solution is a couple of declared (no need to define) functions to test "declare"
and a couple for "declare_new_api"
Now your
decode_for_me()
become