Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[windows] Fix ambiguous call for tf2::convert on MSVC #462

Open
wants to merge 1 commit into
base: noetic-devel
Choose a base branch
from

Conversation

tfoote
Copy link
Member

@tfoote tfoote commented May 13, 2020

  • rework ambiguous call on MSVC.

Forward port of #444 to noetic

@tfoote
Copy link
Member Author

tfoote commented May 13, 2020

@seanyen The patch from #444 doesn't forward port to noetic successfully. Could you take a look at why?

@gleichdick
Copy link

I don't want to be disrespectful, but I pointed out the problem at multiple places. Please correct me if I'm wrong.
The error message from the build is exactly the same as in #430:

11:56:08 test_convert.cpp:(.text._ZN3tf24impl9ConverterILb0ELb0EE7convertINS_10QuaternionEN5Eigen10QuaternionIdLi0EEEEEvRKT_RT0_[_ZN3tf24impl9ConverterILb0ELb0EE7convertINS_10QuaternionEN5Eigen10QuaternionIdLi0EEEEEvRKT_RT0_]+0x45): undefined reference to `void tf2::fromMsg<geometry_msgs::Quaternion_<std::allocator<void> >, Eigen::Quaternion<double, 0> >(geometry_msgs::Quaternion_<std::allocator<void> > const&, Eigen::Quaternion<double, 0>&)'
11:56:08 collect2: error: ld returned 1 exit status

IMHO, the whole conversion stuff boils down to something like (taken from here)

#include <iostream>
namespace msgs {
    struct A_msg { 
        A_msg(){} // for clang
    };
}

namespace datatypes {
    struct B_dt {};
}

namespace tf2 {
    template <class A, class B>
    void fromMsg(const A&, B&);

    template <class A, class B>
    void convert(const A& a, B& b) {
        fromMsg(a, b);
    }

    //template<>
    void fromMsg(const msgs::A_msg& a, datatypes::B_dt& b) {}
}

int main () {
    const msgs::A_msg a;
    datatypes::B_dt b;
    tf2::convert(a, b);
    std::cout << "Hello, world!\n";
}

Compilation/linking fails with GCC, Clang and MSVC (with /permissive- flag set). If you uncomment the template<> statement or if you reorder the tf2 namespace

namespace tf2 {
    void fromMsg(const msgs::A_msg& a, datatypes::B_dt& b) {}

    template <class A, class B>
    void fromMsg(const A&, B&);

    template <class A, class B>
    void convert(const A& a, B& b) {
        fromMsg(a, b);
    }
}

it works fine.

When the conversion is requested, tf2::convert() uses the templated forward declaration for tf2::fromMsg() in tf2/transform_functions.h.
The point is that the corresponding function is not defined as a template specialization in tf2_eigen.h, but as a 'classic' overload. So, this correct overloaded function will only be chosen if it is defined before the generic forward declaration. Otherwise, these linking errors occur. The users have to take care on how they order their header #includes which is very error-prone.

@seanyen
Copy link
Contributor

seanyen commented Sep 10, 2020

@tfoote Sorry this is out of my radar. I will be checking this one soon.

@ahcorde ahcorde added the noetic label Feb 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants