【问题标题】:Function overloading with template and constant pointer使用模板和常量指针的函数重载
【发布时间】:2021-03-15 11:09:45
【问题描述】:

我想要一个通用函数,它需要一个模板并通过函数重载进行一些专门化。但是,当使用关键字常量或使用指针时,会调用错误的函数。 我想要的是:

#include <Eigen/Dense>
#include <iostream>

template <typename T>
void myFunction(const T variable){
    std::cout << "Generic called";
}

void myFunction(const Eigen::MatrixXd* variable){
    std::cout << "Eigen matrix overload";
}

int main(int argc, char **argv) {
    Eigen::MatrixXd my_variables;
    myFunction(&my_variables);
    return 0;
}

这会打印“Generic called”。虽然我希望它会调用重载。

我已经玩了一点。如果没有 const 关键字,我会得到预期的行为:

#include <Eigen/Dense>
#include <iostream>

template <typename T>
void myFunction(T variable){
    std::cout << "Generic called";
}

void myFunction(Eigen::MatrixXd* variable){
    std::cout << "Eigen matrix overload";
}

int main(int argc, char **argv) {
    Eigen::MatrixXd my_variables;
    myFunction(&my_variables);
    return 0;
}

按预期打印“特征矩阵过载”。 并且没有指针:

#include <Eigen/Dense>
#include <iostream>

template <typename T>
void myFunction(const T variable){
    std::cout << "Generic called";
}

void myFunction(const Eigen::MatrixXd variable){
    std::cout << "Eigen matrix overload";
}

int main(int argc, char **argv) {
    Eigen::MatrixXd my_variables;
    myFunction(my_variables);
    return 0;
}

同时打印“特征矩阵过载”。

那么为什么第一个例子不打印“特征矩阵重载”?

编辑: 我发现将 const 放在指针之后确实会调用正确的函数,但这会使我的指针 const 并且我(也)想要我的对象常量。

#include <Eigen/Dense>
#include <iostream>

template <typename T>
void myFunction(const T variable){
    std::cout << "Generic called";
}

void myFunction(Eigen::MatrixXd* const variable){
    std::cout << "Eigen matrix overload";
}

int main(int argc, char **argv) {
    Eigen::MatrixXd my_variables;
    myFunction(&my_variables);
    return 0;
}

使用void myFunction(const Eigen::MatrixXd* const variable) 再次调用泛型函数。

编辑2: blindcrone 的答案解释了为什么第一个选项调用泛型函数。但是有了这个解释,我希望在我的第三个代码块中也会调用泛型(使用 const 但不是指针,也适用于类似于第三个代码块但使用参数作为参考的情况)。有人也可以解释一下吗?

【问题讨论】:

  • 它不会做你想做的,因为const T中的const对重载解析没有任何作用,T是所有东西的完美匹配,而const Eigen::MatrixXd*不是完美匹配为Eigen::MatrixXd*.. 也许你是想写const T*

标签: c++ templates overloading


【解决方案1】:

因为您正在重载函数,所以您依赖于传递给函数的变量类型来调用正确的变量。您的模板函数涵盖了不属于确切类型的任何类型 const Eigen::MatrixXd*

所以在您的第一个示例中,您使用参数 &my_variables 调用 myFunction。由于 my_variables 属于 Eigen::MatrixXd 类型,这意味着 &my_variables 属于 Eigen::MatrixXd* 类型em>。

在 C++ 的类型系统中, const 限定符会更改函数参数的类型。因此,在您的第一个示例中,您调用的是泛型,因为该类型的非常量指针没有重载。通常,当没有更好的函数重载候选者时,在这种情况下可以将非 const 类型隐式转换为相应的 const 类型,因此您可能习惯于调用参数声明为 const 且变量为不是,但由于此函数有可用的泛型,编译器只是选择了泛型,因为函数签名适合调用而无需强制转换。

【讨论】:

  • 嗯,我明白了。同时我玩得更远了,如果我改变我的函数来获取一个常量引用(void myFunction(const Eigen::MatrixXd &amp;variable),那么它确实调用了正确的函数。根据您的解释,我认为它仍然会选择错误的功能。你能解释一下吗?
  • @C.Binair 您将其更改为引用并将调用更改为myFunction(my_variables) ? (即没有&)
  • @largest_prime_is_463035818 是的,我也改了电话
  • 除了我的第一条评论之外,我也不明白为什么我的第三个选项没有指针确实有效。在这种情况下,你给Eigen::MatrixXd,而函数需要const Eigen::MatrixXd。因此,在这种情况下,您还需要一个隐式转换以使其成为 const
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多