【问题标题】:Simple templated function to convert std::vectors - "illegal use of this type as an expression"用于转换 std::vectors 的简单模板函数 - “非法使用这种类型作为表达式”
【发布时间】:2026-02-01 16:50:01
【问题描述】:

我写了一个快速的方法来将 std::vectors 从一种类型转换为另一种类型:

template<class A, class B>
vector<B> ConvertSTDVector_AToB(vector<A> vector)
{
    vector<B> converted_vector;

    for(unsigned int i= 0; i< vector.size(); i++)
        converted_vector.push_back(vector[i]);

    return converted_vector;
}

但编译器在左括号后的行上显示“错误 C2275:'B':非法使用此类型作为表达式”。起初我以为“B”是在其他地方定义的,但是更改两个模板类型名称会导致相同的错误。然后我认为这些类型发生了一些奇怪的事情。但即使将两个模板参数都设为整数也不会改变任何东西。

我一辈子都看不出这种方法有什么问题。 (虽然我觉得我可能只是对一些显而易见的事情视而不见)。

【问题讨论】:

  • 这重新定义了vector的含义:vector&lt;A&gt; vector。它不是命名类型,而是命名函数参数。替换为vector&lt;A&gt; v,代码应该可以编译(demo)。
  • 所以你故意改造std::transform ?
  • @WhozCraig 或 std::copy :)。
  • @WhozCraig 更像std::copy 没有显式转换?
  • @pmr 我认为有一半的标准库算法可以用来执行此操作,现在我考虑得更多。我喜欢布赖恩的=P

标签: c++ templates std


【解决方案1】:

只需重命名参数名称。它的名字隐藏了 std::vector 的名字。

或者按照下面的方式写错行

class vector<B> converted_vector;

即使用 std::vector 的详细类型名称来将其与对象(参数)向量区分开来。

函数的代码可以用不同的方式编写。例如

template<class A, class B>
vector<B> ConvertSTDVector_AToB(vector<A> vector)
{
    class vector<B> converted_vector( vector.begin(), vector.end() );

    return converted_vector;
}

pr

template<class A, class B>
vector<B> ConvertSTDVector_AToB(vector<A> vector)
{
    class vector<B> converted_vector;

    converted_vector.assign( vector.begin(), vector.end() );
    return converted_vector;
}

等等。

【讨论】:

  • +1。我悄悄地建议颠倒模板参数顺序以允许部分扣除A,而不必在调用时指定它。 IE。 auto dst = ConvertSTDVector_AToB&lt;DstType&gt;(src); 应该是合理的,而不强制调用者在模板参数列表中指定 &lt;SrcType,DstType&gt;。不错的答案,顺便说一句。
  • 啊!我知道这会很简单。谢谢!
【解决方案2】:

您实际上不必执行这样的功能,而您所要做的就是使用std::copy,前提是您要转换的对象可以通过提供重载的转换运算符相互转换。就像下面的例子:

#include <vector>
#include <iostream>
#include <algorithm>

class B;

class A {
  friend std::ostream& operator<<(std::ostream &out, A const &a);
  int id;
public:
  A() : id(0) { }
  A(int const _id) : id(_id) { }
  operator B() const; 
};

class B {
  friend std::ostream& operator<<(std::ostream &out, B const &b);
  int id;
public:
  B() : id(0) { }
  B(int const _id) : id(_id) { }
  operator A() const { return A(id); }
};

A::operator B() const { return B(id); }

std::ostream& operator<<(std::ostream &out, A const &a) { return (out << a.id); }
std::ostream& operator<<(std::ostream &out, B const &b) { return (out << b.id); }

int main() {
  std::vector<B> bv{B(1), B(2), B(3), B(4), B(5)};
  std::vector<A> av(bv.size());
  std::vector<B> bbv(bv.size());
  std::copy(bv.begin(), bv.end(), av.begin());
  for(auto i : av) std::cout << i << " ";
  std::cout << std::endl;
  std::copy(av.begin(), av.end(), bbv.begin());
  for(auto i : bbv) std::cout << i << " ";
  std::cout << std::endl;  
  return 0;
}

DEMO

【讨论】:

    最近更新 更多