在C ++中调用模板

时间:2012-09-29 19:20:26

标签: c++ xcode

首先,我必须说我已经完成了第一步C ++,我来自PHP,所以请原谅这个基本问题。我一直在寻找和测试许多替代方案,我似乎无法理解如何做到这一点,在PHP中类似于distance($str1, $str2),以便读取函数distance返回的任何内容。

我要做的是调用一个模板,该模板应该返回2个字符串之间的Levenshtein距离。

这是我的代码

template <class T> unsigned int edit_distance(const T& s1, const T& s2)
{
    const size_t len1 = s1.size(), len2 = s2.size();
    vector<vector<unsigned int> > d(len1 + 1, vector<unsigned int>(len2 + 1));

    d[0][0] = 0;
    for(unsigned int i = 1; i <= len1; ++i) d[i][0] = i;
    for(unsigned int i = 1; i <= len2; ++i) d[0][i] = i;

    for(unsigned int i = 1; i <= len1; ++i)
        for(unsigned int j = 1; j <= len2; ++j)

            d[i][j] = std::min( std::min(d[i - 1][j] + 1,d[i][j - 1] + 1),
                               d[i - 1][j - 1] + (s1[i - 1] == s2[j - 1] ? 0 : 1) );
    return d[len1][len2];
}

string text1="house";
string text2="houses";
edit_distance <int> (text1, text2);

问题出在第edit_distance <int> (text1, text2);行,Xcode提供的错误是:C++ requires a type specifier for all declarations

同样,我知道这一定是非常基本的,但我找不到合适的方法。 任何正确方向的小费都会受到赞赏。

谢谢!

2 个答案:

答案 0 :(得分:1)

为了测试我的怀疑,我接受了你的代码,添加了最小的包含和使用声明,以允许编译器调用edit_distance并编译它。这是我编译的文件的完整内容:

#include <vector>
#include <string>
#include <algorithm>
using std::vector;
using std::string;

template <class T> unsigned int edit_distance(const T& s1, const T& s2)
{
    const size_t len1 = s1.size(), len2 = s2.size();
    vector<vector<unsigned int> > d(len1 + 1, vector<unsigned int>(len2 + 1));

    d[0][0] = 0;
    for(unsigned int i = 1; i <= len1; ++i) d[i][0] = i;
    for(unsigned int i = 1; i <= len2; ++i) d[0][i] = i;

    for(unsigned int i = 1; i <= len1; ++i)
        for(unsigned int j = 1; j <= len2; ++j)

            d[i][j] = std::min( std::min(d[i - 1][j] + 1,d[i][j - 1] + 1),
                               d[i - 1][j - 1] + (s1[i - 1] == s2[j - 1] ? 0 : 1) );
    return d[len1][len2];
}

string text1="house";
string text2="houses";
edit_distance <int> (text1, text2);

我的怀疑被检查出来;我收到以下错误:

main.cpp:26:22: error: C++ requires a type specifier for all declarations
edit_distance <int> (text1, text2);
                     ^~~~~

这是你提到的确切错误,因此我相信你很可能犯了我在测试源代码中包含的错误。大多数有经验的程序员只是假设您的不完整代码是为了简洁而显示的,并且会自动插入一些可以完全避免此错误的周围代码。


你还没有理解的东西似乎是在C ++代码中不仅仅是去任何地方。 C ++程序不仅仅是一系列语句,它们在解释器在源代码中读取它们时执行。

C ++是一种编译语言。该程序是函数,类等的一系列声明和定义。语句,即执行内容的代码,仅在定义内部。你的函数调用edit_distance<int>(text1, text2);不在任何定义中,因此编译器不期待一个语句,也不知道你在说什么。所以把它放在一个定义中。您可能想要使用函数定义:

void foo() {
    string text1="house";
    string text2="houses";
    edit_distance <int> (text1, text2);
}

此外,当执行编译代码时,执行从特殊入口点函数main开始。只有通过此入口点可访问的代码才会被执行。 (实际上这不是真的,但其他案例目前无关紧要。)

因此,您需要一个主函数,最终会导致您想要执行的代码。您可以main拨打上述foo,也可以直接将代码放入main

int main() {
    string text1="house";
    string text2="houses";
    edit_distance <int> (text1, text2);
}

此代码仍然无法编译,因为<int>部分不正确。尖括号内的类型将成为edit_distance函数模板中分配给T的类型:

template <class T> unsigned int edit_distance(const T& s1, const T& s2)

edit_distance<int>表示设置T等于int:

unsigned int edit_distance(const int& s1, const int& s2)

这不是你想要的。您可能希望将T设置为字符串,以便s1和s2参数为字符串。

int main() {
    string text1="house";
    string text2="houses";
    edit_distance<string>(text1,text2);
}

接下来,您可能希望实际看到返回值。使用其他包含在源的开头添加#include <iostream>,然后使用main函数:

int main() {
    string text1="house";
    string text2="houses";
    std::cout << edit_distance<string>(text1,text2) << '\n';
}

Complete, compilable program

答案 1 :(得分:1)

template <class T> unsigned int edit_distance(const T& s1, const T& s2)

类型T可以直接从参数中推断出来。所以根本不需要指定类型。只需致电

edit_distance(text1, text2);

来自一个函数。您可以对模板支持的任何类型执行此操作。如果不支持该类型,则会出现编译时错误。

只有在无法推断出类型时才需要显式指定类型。在您的情况下,您指定的类型<int>与您提供的参数不匹配。