我想编写一个模板函数来将数据从一个数组复制到另一个数组。我只想在程序中处理int
,double
和char*
(字符串)数组。
template<typename T>
void copy_key(T *destination, int destination_index, T *source, int source_index){
if (typeid(T) == typeid(int) or typeid(T) == typeid(double)){
destination[destination_index] = source[source_index];
} else {
// char* case
strcpy(destination[destination_index], source[source_index]);
}
}
如果我如下调用copy_key()
,我将收到错误:无法初始化类型为'double'的类型'char *'的参数。
int main(int argc, const char * argv[]) {
double from_array[3] = {1.0,2.0,3.0};
double to_array[3];
copy_key(to_array, 0, from_array, 2);
std::cout << to_array[0] << std::endl;
return 0;
}
我想如果T
是double
,则不会输入else块。我的问题是如何在我的示例中正确使用模板类型的条件?
答案 0 :(得分:5)
我想如果
T
是double
,则不会输入else块。
你想的没错。但是你对其后果的假设是不正确的。
仅仅因为某些代码不会被执行,并不意味着它与程序的其余部分一起不需要很好地形成。
即使在这种情况下,编译器可能会证明该行不会被执行,但这种证据对于所有可能的程序来说几乎是不可能的,因此它不会影响程序的正确性。
典型的解决方案是使用重载或模板特化:
void copy_key(char *destination, int destination_index, const char *source, int source_index){
strcpy(...);
}
void copy_key(double *destination, int destination_index, double *source, int source_index){
destination[destination_index] ...
}
在即将发布的C ++ 17中,将有constexpr if
允许在单个函数中有条件地编译块。
答案 1 :(得分:3)
在C ++ 17中,您将得到if constexpr
,它只评估if语句的一个分支。
现在,if-part和else-part都必须是类型T
的有效代码。如果您希望它对不同类型的行为不同,则必须专门化模板。
答案 2 :(得分:3)
在C ++ 14及之前,使用template specialization代替条件。
C ++是一种编译语言,没有解释。当为特定的具体用途编译模板化函数时,需要编译整个函数,而不仅仅是恰好采用的分支。编译器通常无法推断出代码对所有输入先验所采用的确切路径。
template<typename T>
void copy_key(T *destination, int destination_index, T *source, int source_index){
destination[destination_index] = source[source_index];
}
template<>
void copy_key(const char** destination, int destination_index, const char** source, int source_index) {
// char* case
strcpy(destination[destination_index], source[source_index]);
}
答案 3 :(得分:1)
不,你不能。放作:
template<typename T>
void copy_key(T *destination, int destination_index, T *source, int source_index){
if (some_condition){ // some_condition met
destination[destination_index] = source[source_index];
} else { // some condition not met
// char* case
strcpy(destination[destination_index], source[source_index]);
}
}
更容易看到。
您需要“条件编译”(模板专业化)