1

我创建了模板函数,它允许我用任何类型的数字、整数、双精度等来调用它......

要调用这个函数,我需要知道一个数字,为​​了得到这个数字,我从控制台(std::cin)读取它。

我想知道 - 如果我必须声明变量类型才能将其传递给函数,那么使用模板的目的是什么?我的意思是,我不会问用户他想传递什么类型的数字,而且我肯定不会为所有数据类型执行 switch 循环以不同地调用函数。

如果有什么不够清楚,让我提供一些简单的例子:

template <typename T>
T sum(T a, T b)
{
   return a + b;
}

int main()
{
   using namespace std;
   int a, b; // here, this line

   cout << "Provide first number: ";
   cin >> a;
   cout << "Provide second number: ";
   cin >> b;
   sum(a, b);
}

我一直在考虑创建另一个模板函数,例如loadVariable(),返回加载的变量,例如:

template <typename T>
T loadVariable(string text)
{
   T var = new T;
   cout << text;
   cin >> var;
   return var;
}

然后做这样的事情:

int main()
{
   using namespace std;
   sum(loadVariable("Provide first number: "), loadVariable("Provide second number: ");
}

但是,它看起来非常难看。

这是使用这种功能的好习惯吗?

或者也许还有其他一些我不知道的很酷的方式?

4

4 回答 4

3

从开发和维护的角度来看,模板有助于避免代码重复(不要重复自己)(尽管编译器会为每个专业化生成代码)。它们还用于执行各种编译时任务与使用模板元编程的运行时任务。

由于 C++ 是静态类型的,因此必须在编译时知道类型,因此必须声明它。有关可以包含多种类型之一的类,请参见 boost::variant。

我认为您对模板的问题更多的是静态类型与动态类型语言的问题。我没有检查它,但我认为 loadVariable() 概念不会编译,因为没有指定模板参数,编译器无法从调用本身派生专业化。您必须拥有loadVariable<int>()loadVariable<double>()在哪里指定模板参数。

问题是您是否需要区分整数或浮点类型。因为您可以将输入变量声明为可以包含任何一个的双精度变量。

这可能只是出于帖子的示例目的的代码,但是这个函数是内存泄漏吗?

template <typename T>
T loadVariable(string text)
{
   T var = new T;
   cout << text;
   cin >> var;
   return var;
}
于 2013-04-20T14:47:35.897 回答
1

使用模板的意义在于,您可能希望在代码中的其他地方sum使用两个不同的类型变量。当然,如果您知道您的代码非常简单,以至于您只能sum使用 types进行调用int,那么您很可能只使用 definesum来获取ints 而不是作为模板。

你的第二个例子loadVariable不能像你描述的那样工作,因为你需要指定模板参数:

sum(loadVariable<float>("Provide first number: "), loadVariable<float>("Provide second number: "));

你当然可以这样写:

float a = loadVariable<float>("Provide first number: ");
float b = loadVariable<float>("Provide second number: ");
sum(a, b);

模板参数必须在编译时知道。模板是一种编译时构造。在代码中的某个位置,您始终可以知道要传递给函数的参数的类型。模板函数的重点是不接受其类型可以以某种方式变化的变量。类型不能变化。它们也是编译时构造。模板函数的重点是为不同类型的函数提供通用实现,以便可以在整个程序的不同位置调用它。

于 2013-04-20T14:03:13.367 回答
0

当你想创建一个函数来对两个 32 位整数求和时,你不需要使用模板。当您需要在许多不同类型中执行相同的操作时,您可以使用模板。例如,假设您要实现一个返回两个元素中最小值的函数。让我们称之为min。在您的程序中,您可能会多次调用该min函数,每次都使用不同类型的参数。如果您不使用模板,您的代码将如下所示:

int min( int a, int b ) { ... }
long min( long a, long b ) { ... }
long long min( long long a, long long b ) { ... }
...
...
...

这样做不是更容易吗:

template< typename T >
T min( T a, T b ) { return a < b; }

在您的情况下,您只需要对整数求和,就不需要使用模板,因为您的函数的参数将始终是int.

总而言之,模板为您提供了编译时的灵活性(@Stephane Rolland),这意味着它们在运行时几乎毫无用处。

于 2013-04-20T14:17:54.263 回答
0

我无法回答所有使用模板的问题,但只举一个例子:
当我们编写一个带有数组形式参数的函数时,例如:

void foo( int arr[] );

如果数组边界的精确值很重要,您可以这样做:

void foo(int (&arr)[12] );

foo() 将只接受大小为 12 的数组!模板会有用:</p>

template <int n>   
void average( int (&ary)[n] ); // let compiler deduce n for us

一个更传统的解决方案是

void average_n( int ary[], int size );

当然,我们可以将这两种方法结合起来:

template <int n>
inline void average( int (&ary)[n] )
    { average_n( ary, n ); }

参考:C++ 常识:基础中级编程,第 6 项. Array Formal Arguments

于 2013-04-20T14:19:48.450 回答