Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a function with C-linkage from template?

Tags:

People also ask

How do I create a function template?

To instantiate a template function explicitly, follow the template keyword by a declaration (not definition) for the function, with the function identifier followed by the template arguments. template float twice<float>( float original ); Template arguments may be omitted when the compiler can infer them.

How do you implement a template function in C++?

Defining a Function TemplateA function template starts with the keyword template followed by template parameter(s) inside <> which is followed by the function definition. In the above code, T is a template argument that accepts different data types ( int , float , etc.), and typename is a keyword.

Does function template work with string?

The template function works for int and char, but not float and string.

Can you make templates in C?

Static templates used in C are similar to the templates from the C++ language, because they depend on the actual type members, such as in the case of a struct . In C, the only native means of creating static templates are through the use of macros.


I may be a little late to know this standard statement, after seeing the SO answer:

[C++11: 7.5/1]

Two function types with different language linkages are distinct types even if they are otherwise identical.

which means, given:

void f1();
extern "C" void f2();

decltype(f1) is not the same as decltype(f2)

A reason that I wasn't aware of it until now is that the major compilers (e.g. g++, clang, vc++...) don't respect this rule. See LIVE DEMO.

But I believe most people (include me) will be happier with the current nonconformant behavior. If a compiler follows the standard, many codes that bridge C and C++ would be broken.

Consider this example:

A library provides C API:

#ifdef __cplusplus
extern "C" {
#endif
void registerCallbackInC(void(*callback)(void*));
#ifdef __cplusplus
}
#endif

To use the library in C++:

void f1(void*)
{
    ...
}

extern "C" void f2(void*)
{
    ...
}

registerCallbackInC(f1); // invalid, f1 has C++ linkage
registerCallbackInC(f2); // OK

To use registerCallbackInC, the callback must have C-linkage as well, however, we can't use extern "C" with template:

extern "C"
{
    template<class T>
    void f(void*); // invalid
}

template<class T>
extern "C" void f2(void*); // invalid

template<class T>
struct F
{
    extern "C" static void f(void*); // invalid
};

This makes it impossible to synthesize a C callback using template, should I consider the requirement a standard defect?