C++ 我可以问一下,根据数据类型,向量push_back的代码为什么不';不行?

C++ 我可以问一下,根据数据类型,向量push_back的代码为什么不';不行?,c++,templates,vector,C++,Templates,Vector,我想根据向量的数据类型用不同的函数填充向量。现在我要考虑三种类型:int、double和string。如果我只考虑int和双,代码工作得很好。但如果我在模板中包含字符串,代码就会失败。我不明白为什么字符串的if语句不起作用。代码如下: #include <iostream> #include <vector> #include <map> #include <string> template <typename T> void fil

我想根据向量的数据类型用不同的函数填充向量。现在我要考虑三种类型:int、double和string。如果我只考虑int和双,代码工作得很好。但如果我在模板中包含字符串,代码就会失败。我不明白为什么字符串的if语句不起作用。代码如下:

#include <iostream>
#include <vector>
#include <map>
#include <string>

template <typename T>
void fillV(std::vector<T> &res) {
    if (std::is_same<T, double>::value ) res.push_back(3.5);
    else if (std::is_same<T, int>::value) res.push_back(2);
    else if (std::is_same<T, std::string>::value) res.push_back(std::string("hello"));
}

int main()
{
    std::vector<std::string> t;
    std::vector<double> t1;
    std::vector<int> t2;
     
    fillV<std::string>(t);
    fillV<double>(t1);
    fillV<int>(t2);
    
    std::cout << t[0] << "\n";
    std::cout << t1[0] << "\n";
    std::cout << t2[0] << "\n";
}
#包括
#包括
#包括
#包括
样板
无效填充(标准::矢量和分辨率){
如果(std::is_same::value)res.push_back(3.5);
如果(std::is_same::value)res.push_back(2);
否则如果(std::is_same::value)res.push_back(std::string(“hello”);
}
int main()
{
std::向量t;
std::向量t1;
std::载体t2;
fillV(t);
fillV(t1);
fillV(t2);
std::cout;std::vector::value\u type=std::basic\u string]
推回(常量值类型和x)
^~~~~~~~~
/usr/include/c++/6/bits/stl_vector.h:914:7:注意:参数1从'int'到'const value_type&{aka const std::basic_string&}的转换未知
/usr/include/c++/6/bits/stl_vector.h:932:7:注:候选:void std::vector::push_back(std::vector::value_type&)[带std=std::basic_string;_Alloc=std::Alloc=allocator>;std::vector::value_type=std::basic_string]
推回(值类型和值x)
^~~~~~~~~
/usr/include/c++/6/bits/stl_vector.h:932:7:注意:参数1从'int'到'std::vector>的转换未知::value_type&&{aka std::basic_string&}
main.cpp:在“void fillV(std::vector&)[with T=double]的实例化中:
main.cpp:28:21:从这里开始需要
main.cpp:18:51:错误:调用“std::vector::push_back(std::string)”时没有匹配函数
否则如果(std::is_same::value)res.push_back(std::string(“hello”);
^~~
在/usr/include/c++/6/vector:64:0中包含的文件中,
来自main.cpp:10:
/usr/include/c++/6/bits/stl_vector.h:914:7:注:候选:void std::vector::push_back(const value_type&)[带_Tp=double;_Alloc=std::分配器;std::vector::value_type=double]
推回(常量值类型和x)
^~~~~~~~~
/usr/include/c++/6/bits/stl_vector.h:914:7:注意:参数1从'std::string{aka std::basic_string}'到'const value_type&{aka const double&}没有已知的转换
/usr/include/c++/6/bits/stl_vector.h:932:7:注:候选:void std::vector::push_back(std::vector::value_type&)[with-Tp=double;_Alloc=std::分配器;std::vector::value_type=double]
推回(值类型和值x)
^~~~~~~~~
/usr/include/c++/6/bits/stl_vector.h:932:7:注意:参数1从'std::string{aka std::basic_string}'到'std::vector::value_type&&{aka double&}没有已知的转换
main.cpp:void fillV(std::vector&)[with T=int]的实例化中:
main.cpp:29:18:从这里开始需要
main.cpp:18:51:错误:调用“std::vector::push_back(std::string)”时没有匹配函数
否则如果(std::is_same::value)res.push_back(std::string(“hello”);
^~~
在/usr/include/c++/6/vector:64:0中包含的文件中,
来自main.cpp:10:
/usr/include/c++/6/bits/stl_vector.h:914:7:注:候选:void std::vector::push_back(const value_type&)[使用_Tp=int;_Alloc=std::分配器;std::vector::value_type=int]
推回(常量值类型和x)
^~~~~~~~~
/usr/include/c++/6/bits/stl_vector.h:914:7:注意:参数1从'std::string{aka std::basic_string}'到'const value_type&{aka const int&}没有已知的转换
/usr/include/c++/6/bits/stl_vector.h:932:7:注:候选:void std::vector::push_back(std::vector::value_type&)[with-Tp=int;_Alloc=std::Alloc=分配器;std::vector::value_type=int]
推回(值类型和值x)
^~~~~~~~~
/usr/include/c++/6/bits/stl_vector.h:932:7:注意:参数1从'std::string{aka std::basic_string}'到'std::vector::value_type&&{aka int&}没有已知的转换
于2021年4月14日更新: 由于我不能回答我自己的问题,我将添加一个解决方案,而不是重载,这是通过部分模板专门化实现的。它在C++17之前工作。代码受第一个答案的启发,谢谢

template <typename T, int i>
struct test;

template <typename T>
struct test<T, 1> {
    void fillV(std::vector<T> &res) {
    res.push_back(3.5);
}
};

template <typename T>
struct test<T, 2> {
    void fillV(std::vector<T> &res) {
    res.push_back(2);
}
};

template <typename T>
struct test<T, 3> {
    void fillV(std::vector<T> &res) {
    res.push_back("Hello");
}
};

int main()
{
    std::vector<std::string> t;
    std::vector<double> t1;
    std::vector<int32_t> t2;
     
    test<double, 1> a1;
    a1.fillV(t1);
    test<int32_t, 2> a2;
    a2.fillV(t2);
    test<std::string, 3> a;
    a.fillV(t);
    
    std::cout << t[0] << "\n";
    std::cout << t1[0] << "\n";
    std::cout << t2[0] << "\n";
}
模板
结构测试;
样板
结构测试{
无效填充(标准::矢量和分辨率){
res.push_back(3.5);
}
};
样板
结构测试{
无效填充(标准::矢量和分辨率){
res.push_back(2);
}
};
样板
结构测试{
无效填充(标准::矢量和分辨率){
res.push_back(“你好”);
}
};
int main()
{
std::向量t;
std::向量t1;
std::载体t2;
试验a1;
a1.fillV(t1);
试验a2;
a2.fillV(t2);
试验a;
a、 fillV(t);

std::cout
if
在运行时执行分派。在编译时,所有
if
部分和
else
部分都需要有效,无论
T
是什么

您可以更改为(从C++17开始)

如果值为true,则放弃语句false(如果存在),否则放弃语句true

如果constexpr If语句出现在模板化实体内,并且实例化后条件不依赖于值,则在实例化封闭模板时不会实例化丢弃的语句

例如


if
在运行时执行分派。在编译时,所有
if
部分和
else
部分都需要有效,无论
T
是什么

您可以更改为(从C++17开始)

如果值为true,则放弃语句false(如果存在),否则放弃语句true

如果constexpr If语句出现在模板化实体内,并且实例化后条件不依赖于值,则在实例化封闭模板时不会实例化丢弃的语句

例如

太谢谢你了
template <typename T, int i>
struct test;

template <typename T>
struct test<T, 1> {
    void fillV(std::vector<T> &res) {
    res.push_back(3.5);
}
};

template <typename T>
struct test<T, 2> {
    void fillV(std::vector<T> &res) {
    res.push_back(2);
}
};

template <typename T>
struct test<T, 3> {
    void fillV(std::vector<T> &res) {
    res.push_back("Hello");
}
};

int main()
{
    std::vector<std::string> t;
    std::vector<double> t1;
    std::vector<int32_t> t2;
     
    test<double, 1> a1;
    a1.fillV(t1);
    test<int32_t, 2> a2;
    a2.fillV(t2);
    test<std::string, 3> a;
    a.fillV(t);
    
    std::cout << t[0] << "\n";
    std::cout << t1[0] << "\n";
    std::cout << t2[0] << "\n";
}
void fill_v(std::vector<double>& res) { res.push_back(3.5); }
void fill_v(std::vector<int>& res) { res.push_back(2); }
void fill_v(std::vector<std::string>& res) { res.push_back(std::string("hello")); }

int main()
{
    std::vector<std::string> t;
    std::vector<double> t1;
    std::vector<int32_t> t2;

    fillV(t1);
    fillV(t2);
    fillV(t);

    std::cout << t[0] << "\n";
    std::cout << t1[0] << "\n";
    std::cout << t2[0] << "\n";
}

template <typename T>
void fillV(std::vector<T> &res) {
    if constexpr (std::is_same<T, double>::value ) res.push_back(3.5);
    else if constexpr (std::is_same<T, int>::value) res.push_back(2);
    else if constexpr (std::is_same<T, std::string>::value) res.push_back(std::string("hello"));
}
void fill_v(std::vector<double>& res) { res.push_back(3.5); }
void fill_v(std::vector<int>& res) { res.push_back(2); }
void fill_v(std::vector<std::string>& res) { res.push_back(std::string("hello")); }

template <typename T>
void fillV(std::vector<T> &res) {
    if (std::is_same<T, double>::value ) fill_v(res);
    else if (std::is_same<T, int>::value) fill_v(res);
    else if (std::is_same<T, std::string>::value) fill_v(res);
    // or just 
    // fill_v(res);
}