Можно ли определить тип функции указателя на внешнюю "C" в шаблоне? - PullRequest
9 голосов
/ 01 февраля 2011

Я хочу добавить общедоступный typedef в шаблон для указателя на аргумент "Взять один аргумент", который использует языковую связь "C".

Я пытался:

extern "C" {
    template <typename return_t_, typename arg1_t_>
    struct test
    {
        typedef return_t_ (*C_fun1_t)(arg1_t_);
    };
}

И:

template <typename return_t_, typename arg1_t_>
struct test
{
    extern "C" {
        typedef return_t_ (*C_fun1_t)(arg1_t_);
    }
};

И:

template <typename return_t_, typename arg1_t_>
struct test
{
    extern "C" typedef return_t_ (*C_fun1_t)(arg1_t_);
};

без успеха.

Возможно ли то, что я пытаюсь достичь?

Ответы [ 3 ]

10 голосов
/ 01 февраля 2011

C ++ 03, §7.5p4:

Спецификация связи должна встречаться только в области пространства имен.… Связывание языка AC игнорируется для имен членов класса и типа функции-члена функций класса.

К сожалению, вы просто не можете сделать это в текущем C ++.Этот текст не изменился в последней версии C ++ 0x, но «шаблонные определения типа» могут выполнить это.

1 голос
/ 01 февраля 2011

Рассмотрим typedef объектов boost::function или функций STL ... также вы не можете определить шаблон внутри внешнего блока "C" по некоторым вполне очевидным причинам, если подумаете об этом.

0 голосов
/ 01 февраля 2011

Мне кажется, что все работает нормально, если я просто опущу extern "C" в вашем typedef. То есть следующие компиляции, ссылки и запускаются без предупреждений, ошибок или проблем:

foo.c:

#include <stdio.h>
int foo(int x) {
    return printf("%x\n", x);
}

test.cpp:

extern "C" int foo(int);

template <typename return_t_, typename arg1_t_>
struct test
{
    typedef return_t_ (*C_fun1_t)(arg1_t_);
    C_fun1_t myFn;
};

int main() {
    test<int, int> t;
    t.myFn = foo;
    return t.myFn(5);
}

Для гуру C ++: я не знаю тонкости того, что отличает связь C от C ++. Есть ли какие-то скрытые проблемы, которые не могли бы появиться в простом примере, подобном этому?

...