将模板参数限制为仅具有不同构造函数签名的 类 组
limiting template arguments to only set of classes that have different constructor signature
我的项目中有许多 classes 作为消息。
还有一个模板函数,它接受 class 类型并使用它做一些工作。
template <typename T>
static int SendBroadcastMsg(T msg)
{
//....do something
return 0; //return an int result once finished.
}
在我的主体中,我有一堆使用此模板发送的消息。但我想将模板参数限制为仅 Message
和 AnotherMsg
类型。
SendBroadcastMsg<Message>(1); //should be valid
SendBroadcastMsg<AnotherMsg>({ true, 2 }); //should be valid
SendBroadcastMsg<NotAMsg>(1);//shoud NOT be valid.
SendBroadcastMsg<NotAMsg>({ false, 1 });// should NOT be valid.
我找到了一些答案 here 但我似乎无法让它工作。我怀疑它可能是由于这些 classes 的构造函数中有参数,但我不确定如何处理它。任何帮助将不胜感激。
完整代码:
#include <iostream>
#include <memory>
#include <vector>
struct Message
{
Message( const int val) : Val(val) {}
int Val;
};
struct AnotherMsg
{
AnotherMsg( const bool con, int val) : Cond(con), Val(val){}
bool Cond;
int Val;
};
struct NotAMsg
{
NotAMsg(const int val) : Val(val), Cond(false){}
NotAMsg(const bool con, int val) : Cond(con), Val(val){}
bool Cond;
int Val;
};
//template function wrapper.
template <typename T>
static int SendBroadcastMsg(T msg)
{
//....do something
return 0; //return an int result once finished.
}
template <typename T>
constexpr bool is_ValidMsg()
{
return std::is_same<T, Message>(const int) || std::is_same<T, AnotherMsg>(const bool, int);
}
template <typename T>
using common_byfunc = typename std::conditional<is_ValidMsg<T>(), NotAMsg, T>::type;
static_assert(std::is_same <common_byfunc<Message>, NotAMsg>(), "");
static_assert(std::is_same <common_byfunc<AnotherMsg>, NotAMsg>(), "");
int main()
{
SendBroadcastMsg<Message>(1);
SendBroadcastMsg<AnotherMsg>({ true, 2 });
SendBroadcastMsg<NotAMsg>(1);//shoud not be valid.
SendBroadcastMsg<NotAMsg>({ false, 1 });// should not be valid.
return 0;
}
正确的语法(一个可能的正确语法)是
template <typename T>
constexpr bool is_ValidMsg()
{
return std::is_same<T, Message>::value || std::is_same<T, AnotherMsg>::value;
}
我的意思是...我不知道你是什么意思
std::is_same<T, Message>(const int)
和
std::is_same<T, AnotherMsg>(const bool, int)
但他们错了。
如果你想避免SendBroadcastMsg()
被非消息类型编译,你可以使用is_ValidMsg()
到SFINAE enable/disable它。
有很多方法;举个例子
template <typename T>
static std::enable_if_t<is_ValidMsg<T>(), int> SendBroadcastMsg(T msg)
{
//....do something
return 0; //return an int result once finished.
}
但是记得在SendBroadcasMsg()
之前定义is_ValidMsg()
另一种可能的解决方案是在 SendBroadcastMsg()
中的简单 static_assert()
中使用 is_ValidMsg()
template <typename T>
static int SendBroadcastMsg(T msg)
{
static_assert( is_ValidMsg<T>(), "!" );
//....do something
return 0; //return an int result once finished.
}
我的项目中有许多 classes 作为消息。 还有一个模板函数,它接受 class 类型并使用它做一些工作。
template <typename T>
static int SendBroadcastMsg(T msg)
{
//....do something
return 0; //return an int result once finished.
}
在我的主体中,我有一堆使用此模板发送的消息。但我想将模板参数限制为仅 Message
和 AnotherMsg
类型。
SendBroadcastMsg<Message>(1); //should be valid
SendBroadcastMsg<AnotherMsg>({ true, 2 }); //should be valid
SendBroadcastMsg<NotAMsg>(1);//shoud NOT be valid.
SendBroadcastMsg<NotAMsg>({ false, 1 });// should NOT be valid.
我找到了一些答案 here 但我似乎无法让它工作。我怀疑它可能是由于这些 classes 的构造函数中有参数,但我不确定如何处理它。任何帮助将不胜感激。
完整代码:
#include <iostream>
#include <memory>
#include <vector>
struct Message
{
Message( const int val) : Val(val) {}
int Val;
};
struct AnotherMsg
{
AnotherMsg( const bool con, int val) : Cond(con), Val(val){}
bool Cond;
int Val;
};
struct NotAMsg
{
NotAMsg(const int val) : Val(val), Cond(false){}
NotAMsg(const bool con, int val) : Cond(con), Val(val){}
bool Cond;
int Val;
};
//template function wrapper.
template <typename T>
static int SendBroadcastMsg(T msg)
{
//....do something
return 0; //return an int result once finished.
}
template <typename T>
constexpr bool is_ValidMsg()
{
return std::is_same<T, Message>(const int) || std::is_same<T, AnotherMsg>(const bool, int);
}
template <typename T>
using common_byfunc = typename std::conditional<is_ValidMsg<T>(), NotAMsg, T>::type;
static_assert(std::is_same <common_byfunc<Message>, NotAMsg>(), "");
static_assert(std::is_same <common_byfunc<AnotherMsg>, NotAMsg>(), "");
int main()
{
SendBroadcastMsg<Message>(1);
SendBroadcastMsg<AnotherMsg>({ true, 2 });
SendBroadcastMsg<NotAMsg>(1);//shoud not be valid.
SendBroadcastMsg<NotAMsg>({ false, 1 });// should not be valid.
return 0;
}
正确的语法(一个可能的正确语法)是
template <typename T>
constexpr bool is_ValidMsg()
{
return std::is_same<T, Message>::value || std::is_same<T, AnotherMsg>::value;
}
我的意思是...我不知道你是什么意思
std::is_same<T, Message>(const int)
和
std::is_same<T, AnotherMsg>(const bool, int)
但他们错了。
如果你想避免SendBroadcastMsg()
被非消息类型编译,你可以使用is_ValidMsg()
到SFINAE enable/disable它。
有很多方法;举个例子
template <typename T>
static std::enable_if_t<is_ValidMsg<T>(), int> SendBroadcastMsg(T msg)
{
//....do something
return 0; //return an int result once finished.
}
但是记得在SendBroadcasMsg()
is_ValidMsg()
另一种可能的解决方案是在 SendBroadcastMsg()
static_assert()
中使用 is_ValidMsg()
template <typename T>
static int SendBroadcastMsg(T msg)
{
static_assert( is_ValidMsg<T>(), "!" );
//....do something
return 0; //return an int result once finished.
}