我想将函数作为模板参数传递,但是以某种方式我无法使其正常工作。过去,我已经写了很多模板类,但是只使用“普通”类型作为参数。我已经搜索了该问题,但似乎没有合适的解决方案。所以我被卡住了。
这是我要实现的目标: 我有几个要封装的类型特定的库函数。我知道也有其他方法可以做到这一点(例如继承),但是由于我也想在这里学一点点,因此我想使用模板方法来完成它。
我要实现的目标:
MyType<int> myIntObject(...);
...
int writeVal = 10;
myIntObject.Write(writeVal);
...
int readVal;
myIntObject.Read(&readVal);
也许也使用typedefs:
typedef MyType<int> MyIntType;
我到目前为止所做的事情:
template<typename T>
struct SetFunction
{
inline ret_code operator()(someArgs, T value) const {return E_Fail;}
}
template<typename T>
struct GetFunction
{
inline ret_code operator()(someArgs, T& value) const {return E_Fail;}
}
//template specialization:
template<>
struct SetFunction<int>
{
inline ret_code operator()(someArgs, T value) const
{
//some other code
return libraryFunctionWriteInt(someArgs, value);
}
}
template<>
struct GetFunction<int>
{
inline ret_code operator()(someArgs, T& value) const
{
//some other code
return libraryFunctionReadInt(someArgs, &value);
}
}
//do the specialization for all other types as well
template<class T, typename T_get_function = GetFunction<T>(), typename T_set_function = SetFunction<T>()>
MyType
{
public:
MyType(someArgs)
{
if(T_get_function(someArgs, &_value) == E_Fail)
{
throw someting;
}
}
bool SetValue(T value)
{
_value = value;
//maybe some other code
return T_set_function(someArgs, _value) == E_Success;
}
bool GetValue(T &value)
{
//maybe some other code
return T_get_function(someArgs, &_value) == E_Success;
}
private:
T _value;
}
//and then eventually using it (maybe using some typedefs as well)
MyType<int> myIntObject(someArgs);
...
int writeVal = 10;
myIntObject.SetValue(writeValue);
...
int readVal;
myIntObject.GetValue(&readValue);
现在我得到编译错误:表达式列表在函数转换中被视为复合表达式,在我称为T_set_function / T_get_function
的这两行中。我还尝试过直接将库函数作为模板参数传递,并且没有设置任何默认函数,但我也无法使其正常工作。
到目前为止,我几乎阅读的所有书籍,文章和示例都只处理传递“普通”类型作为模板参数,但是由于stl也使用传递函数,所以我真的很想知道如何做到这一点。
>答案 0 :(得分:1)
关于运算符的参数有一些不完整的代码,但是语法
template<class T, typename T_get_function = GetFunction<T>(),
typename T_set_function = SetFunction<T>()>
不正确。 typename T_get_function =
建议使用模板的类型参数,而=之后是表达式GetFunction<T>()
,而不是声明符。
应该是
template<class T, typename T_get_function = GetFunction<T>,
typename T_set_function = SetFunction<T>>
然后,您不清楚T_get_function::operator()
在没有类实例的情况下如何工作。应该是静态的,还是应该有一个实例。
template<class T, T_get_function getter = GetFunction<T>{},
T_set_function setter = SetFunction<T>>{}
在这种特殊情况下, typename
和class
表示同一件事,在那儿并不需要。但是我们不知道那里是T_get_function
吗?将其作为模板的类参数并分配默认类是C ++ 20功能。
Operator&返回指向变量的指针,您不能将其用作引用(也不需要这样做)。 该元代码包含几十个问题,从丢失到丢失;错误的语法以及缺少的关键字和声明。如果您在2020年之前专注于C ++标准,则应该从头开始重写它,否则请使用克劳斯的答案作为指导。
答案 1 :(得分:1)
我不知道是否抓住了您的问题,但是从标题上我读到您想将函数作为模板参数传递。即使您是否需要使用函数参数以及是否需要返回值,这也很容易。
示例:
template < auto func >
struct X
{
template < typename ... PARMS >
static auto call(PARMS&& ... parms)
{
return func(parms...);
}
};
void func1() { std::cout << "1" << std::endl; }
void func2(int value ) { std::cout << "2 with " << value << std::endl; }
int func3() { std::cout << "With retval" << std::endl; return 987; }
int main()
{
X<func1>::call( );
X<func2>::call( 123 );
std::cout << "Get retval" << X<func3>::call() << std::endl;
}
答案 2 :(得分:1)
GetFunction<T>
和SetFunction<T>
是仿函数,因此您需要一个实例来调用其call operator
。
您可以更换这些零件
bool SetValue(T value)
{
_value = value;
//maybe some other code
return T_set_function{ /*Functor constructed*/ }(someArgs, _value) == E_Success;
}
bool GetValue(T &value)
{
//maybe some other code
return T_get_function{ /*Functor constructed*/ }(someArgs, &_value) == E_Success;
}
if(T_get_function{ /*Functor constructed*/ }(someArgs, &_value) == E_Fail)
{
throw someting;
}
正如@ Swift-FridayPie所说,您还需要重新安排模板参数部分。