0
#include <string>
#include <sstream>
#include <iostream>

extern "C" {

struct A {
public:
#ifdef __cplusplus
    //extern "C++" {
    template<typename T>
    T to_string(T value) {
        return value;
    }

    //}
#endif /* __cplusplus */
};
}
int main() {
    A a;
    std::cout << a.to_string<int>(1);
    return 0;
}

How to handle situation like this to keep the main function can execute correctly? To make struct A able to use its member function.

Since it seems unable to use extern "C++" in a struct and it will report error templates must have C++ linkage currently.

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234
Victor
  • 1
  • 1
  • This doesn't really make sense. `extern "C"` can only be used with C++, so the `#ifdef` will always be true. – Barmar Jul 09 '22 at 04:10
  • I don't think you need to put this structure in `extern "C"`. It doesn't have a contrstructor, destructor, or virtual members, so it's a POD structure and should be compatible with C automatically. See https://stackoverflow.com/questions/146452/what-are-pod-types-in-c – Barmar Jul 09 '22 at 04:17
  • Yes, you'r right. Actually this problem came from a project which may use C to call the program, I simply abstract the problem and seek for some way to make this program run successfully by modifying the code inside `extern "C"` with `#ifdef __cplusplus`. – Victor Jul 09 '22 at 04:18
  • Generally only function declarations have to be put into `extern "C"`, so that the names won't be mangled. – Barmar Jul 09 '22 at 04:19
  • Removed a duplicate of https://stackoverflow.com/questions/4877705/why-cant-templates-be-within-extern-c-blocks, the question there is different (and not answered properly). I am adding my answer there too. – n. m. could be an AI Jul 09 '22 at 05:01
  • A `to_string` function that returns `int`? A member function that accesses none of it's member variables? An empty struct? Looks like you simplified this code beyond the point where the question makes sense. – Goswin von Brederlow Jul 09 '22 at 10:57

1 Answers1

1

dcl.link All functions and variables whose names have external linkage and all function types have a language linkage.

Class types do not. Wrapping a struct in extern "C" has no effect.

dcl.link Linkage from C++ to objects defined in other languages and to objects defined in C++ from other languages is implementation-defined and language-dependent. Only where the object layout strategies of two language implementations are similar enough can such linkage be achieved.

You should just #ifdef out C++-specific parts of your struct, such as access specifications and member functions, and hope (or find in the platform documentation) that your C compiler produces a struct with the layout identical to that produced by the C++ compiler.

struct A {
#ifdef __cplusplus
  public:
    template<typename T>
    T to_string(T value) {
        return value;
    }
#endif /* __cplusplus */
};
n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243