Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 需要类型参数特定代码时是否应使用模板?_C++_Metaprogramming - Fatal编程技术网

C++ 需要类型参数特定代码时是否应使用模板?

C++ 需要类型参数特定代码时是否应使用模板?,c++,metaprogramming,C++,Metaprogramming,假设我们有一个类负责设置SQL语句的值,如下所示: void MySqlPreparedStatement::SetString(uint32_t paramIndex, const std::string& value); void MySqlPreparedStatement::SetBinary(uint32_t paramIndex, const void* value, size_t length); void MySqlPreparedStatement::SetUInt64

假设我们有一个类负责设置SQL语句的值,如下所示:

void MySqlPreparedStatement::SetString(uint32_t paramIndex, const std::string& value);
void MySqlPreparedStatement::SetBinary(uint32_t paramIndex, const void* value, size_t length);
void MySqlPreparedStatement::SetUInt64(uint32_t paramIndex, const uint64_t value);
void MySqlPreparedStatement::SetInt64(uint32_t paramIndex, const int64_t value);
// ...
所有这些“set”方法都有它们共同的代码,但仍有一些代码取决于用户正在设置的值的类型(例如,
m_参数[paramIndex]。buffer_type=MYSQL_type_LONGLONG;
表示64位整数,
m_参数[paramIndex]。buffer_type=MYSQL_type_LONG;
表示32位整数)


在这种情况下,哪一种做法更好?将所有这些“set”方法封装在一个模板方法中(这将使我在每个接受的类型参数上创建一些开关/大小写,以获得
缓冲区类型的正确值
)或者像我上面展示的声明一样,为每种接受的值类型声明不同的方法?

最合适的方法在很大程度上取决于函数中包含的代码

如果您可以清楚地分离特定代码和公共相同代码,那么将此相同代码封装在单独的函数中,并从包含特定部分的较小函数中调用该函数可能更合适(稍微缩短签名):

(根据你的评论,在你的具体例子中似乎就是这样。)

但是,如果您混合使用公共代码和特定代码(扩展视图),则情况会发生变化:

您真的想为每个函数实现该模式吗?虽然上述情况可能是一种极端情况,但如果函数变得更复杂,最好使用模板:

template <typename T>
void setParameter(T const& value)
{
    firstCommonFunction(/*...*/);
    firstSpecificFunction<T>(/*...*/);
    secondCommonFunction(/*...*/);
    secondSpecificFunction<T>(/*...*/);
    thirdCommonFunction(/*...*/);
    thirdSpecificFunction<T>(/*...*/);
    fourthCommonFunction(/*...*/);
}
模板
void设置参数(T常量和值)
{
firstCommonFunction(/*…*/);
FirstSpecific函数(/*…*/);
第二公共函数(/*…*/);
第二个特定函数(/*…*/);
第三个公共函数(/*…*/);
第三个指定函数(/*…*/);
第四公共函数(/*…*/);
}
现在,模板可以确保所有函数的行为都相同,在适当的时候调用公共函数和特定函数


不管怎样,如果你的函数在设计上都是这样的话,那就好了。然而,仅仅为了拥有一个模板而人为地强制执行这样的设计通常不是一个好主意…

constexpr,如果你的朋友在这里,以及。我不认为有一个通用的建议是不会固执己见的。就我个人而言,我更喜欢一堆小的重载,而不是一个单一的函数模板。@Aconcagua来看看。但是,您有什么要补充的吗?哪一个是最佳做法?要重载方法或使用一个模板方法?模板化函数最基本的本质上是一个无界相关函数族的规范,所有函数都执行(基本上)类似的操作。根据您的描述,您有一个小的函数族(用于字符串、任意数据、32位整数(有符号和无符号)和64位整数(有符号和无符号)-每个函数都与一些独特的行为(例如,给定给
m_参数[paramIndex]的值)。缓冲区类型
)。基于这一点,我会编写一小部分重载函数,而不是模板。@andresantacruz因此,常见的代码是100%相同的,与参数类型无关。然后,模板看起来并不真正合适。请注意,每个模板实例化都是一个单独的函数,然后您会复制编译后的代码。因此,具有最小的(可能是内联的)函数所有调用公共(可能是适当参数化的)函数的函数都可能是首选的。。。
void setInt32(int32_t value)
{
    firstCommonFunction(/*...*/);
    // some specific code
    secondCommonFunction(/*...*/);
}
template <typename T>
void setParameter(T const& value)
{
    firstCommonFunction(/*...*/);
    firstSpecificFunction<T>(/*...*/);
    secondCommonFunction(/*...*/);
    secondSpecificFunction<T>(/*...*/);
    thirdCommonFunction(/*...*/);
    thirdSpecificFunction<T>(/*...*/);
    fourthCommonFunction(/*...*/);
}