从模板函数返回向量

Returning vector from template function

本文关键字:返回 向量 函数      更新时间:2023-10-16

希望在这里得到一些澄清。下面的代码执行良好,但当我取消注释else语句时,会发生编译错误。这是因为在main中,我指定了一个类型为int的事件,尽管有可能是类型string。我已经将我的实际代码简化为下面的内容,以缩小问题的范围,我该怎么做才能使main中的向量data可以是getNextLineOfData返回的任何类型?

#include <vector>
using namespace std;
template< typename T>
std::vector<T> getNextLineOfData(bool someBoolean)
    {
        std::vector<T> data;
        if (someBoolean)
        {
            data.push_back(1);
            data.push_back(2);
            data.push_back(3);
        }
        /*
        else
        {
            data.push_back("1");
            data.push_back("2");
            data.push_back("3");
        }
        */
return data;
    };
int main()
{
vector<int> data = getNextLineOfData<int>(true);
return 0;
}

您在代码片段中将编译时操作与运行时操作混淆。当您模板化函数getNextLineOfData并用getNextLineOfData<int>实例化它时,编译器会继续生成一个为您返回向量的函数。但是,if语句仅在运行时求值。因此,当编译器试图构建代码时,它会看到您正在根据条件将1"1"添加到vector<int>容器中。这是不允许的。你可以通过模板专业化来解决你的问题。

#include <vector>
using namespace std;
template<typename T>
std::vector<T> getNextLineOfData() {
  // default
}
template<>
std::vector<int> getNextLineOfData()
    {
        std::vector<int> data;
            data.push_back(1);
            data.push_back(2);
            data.push_back(3);
            return data;
    };
template<>
std::vector<std::string> getNextLineOfData()
    {
        std::vector<std::string> data;
            data.push_back("1");
            data.push_back("2");
            data.push_back("3");
            return data;
    };
int main()
{
    vector<int> data = getNextLineOfData<int>();
    return 0;
}

EDIT:正如@BobTFish所指出的,最好重载函数,而不是模板专门化它。上面的解决方案以最初设置的方式解决了这个问题。

阅读评论中的额外信息,我建议这样做:

void getNextLine(std::vector<std::string>& output)
{
    output.push_back("string data as you please");
}
void getNextLine(std::vector<int>& output)
{
    output.push_back(1);
}
bool nextLineIsIntData()
{
    // somehow determine if the coming data is strings or ints
    return false;
}
int main()
{
    std::vector<std::string> stringData;
    std::vector<int> intData;
    if (nextLineIsIntData())
        getNextLine(intData);
    else 
        getNextLine(stringData);
    // do whatever you want
}

你所做的完全是非法的。当查看if-else语句时,您会说,如果某个条件为true,则将执行,但不会执行,因此编译器将忽略未执行的部分也是合理的。这完全是错误的。您需要做的是,对于不同的数据类型,过于重载或专门化函数。

我还应该提到,你试图做的是糟糕的风格。您本质上也依赖于用户传递正确的bool值,这会影响push_back()到向量中的类型。当你拥有模板模式匹配的能力,完全不需要依赖正确的用户输入时,为什么要这样做呢。

在这种情况下以及您遇到的任何类似情况下,最好让编译器决定