c++variadic-templatesvariadic-functionsextern

Is it possible to somehow contain an extern "C" function within a header file?


Due to templates being templates, they need to be defined in a header file (making explicit instantiations is not an option). I have an extern function which takes an expanded template parameter pack:

#pragma once

extern "C" int bar(...);

class Foo {
    template <typename ...Args>
    int foo(Args&&... args) {
        return bar(args...);
    }
};

I thought about it for quite a while, and I can't figure out how to decouple this. I don't want bar to be in the header and the consumers of said header to have access to it, but because templates must be in a header file, I can't make a wrapper function that would contain the extern. The extern function cannot take va_list.

Is this even possible to do in a portable (compiler agnostic) way?

PS: the extern could be really anywhere, as long as it would somehow bypass templates requirement to be withing the header, and not be accessible to consumers of the header.


Solution

  • Language specifications can only appear in namespace scope, so you cannot restrict the declaration to the function :-/

    One workaround which should work (maybe except for Oracle Studio See note #1) would be to use function pointer:

    class Foo
    {
        static int (* const fbar) (...);
    public:
    
        template <typename ...Args>
        int foo(Args&&... args) {
            return fbar(args...);
        }
    };
    

    and in cpp:

    extern "C" int bar(...);
    
    int (* const Foo::fbar)(...) = &bar;
    

    Note #1:

    According to cppreference

    The only modern compiler that differentiates function types with "C" and "C++" language linkages is Oracle Studio [..]

    So I'm unsure it would work for that compiler directly (maybe a extra cast would be required).