ошибка связывания шаблона - PullRequest
0 голосов
/ 20 января 2012

У меня есть заголовок, в который я помещаю определение шаблона функции:

template <typename FT, typename std::enable_if< !std::is_array<FT>::value, int >::type =0 >
int fieldRW(lua_State* l, FT* ptr, bool write){ return scalarFieldRW<FT>(l, ptr, write); }

в блоке .cpp Я получаю указатель на эту функцию шаблона и ожидаюкомпилятор для создания шаблона:

typedef int (*_fieldRW)(lua_State*, void*, bool);
int dummy=3;
_fieldRW aFunctionPointer=_fieldRW(fieldRW<decltype(dummy)>);

Все компилируется.Но я получаю следующую ошибку времени ссылки:

/ home / pisto / sorgenti / hopmodv4 / src / fpsgame / server.cpp: 39: неопределенная ссылка на `int fieldRW (lua_State *, int *, bool) '

Обратите внимание, что компилятор правильно выбирает шаблон, определенный в заголовке (поскольку он добавляет второй аргумент шаблона по умолчанию), но, по-видимому, ему не удается создать экземпляр шаблона.

РЕДАКТИРОВАТЬ: это определенно похоже на ошибку.Смотрите эти тесты: http://pastebin.com/5Yjsv47H Кроме того, еще один признак того, что это, вероятно, ошибка в g ++, заключается в том, что если я сделаю это:

int main() {
        int dummy=3;
        int (*inted)(int*)=asd<decltype(dummy)>;
        int (*voided)(void*)=(int (*)(void*))asd<decltype(dummy)>;
        voided(&dummy);
}

g ++ предупреждает о неиспользуемой переменной inted, нопрекрасно компилируется.

1 Ответ

1 голос
/ 22 января 2012

Ответ, вероятно, является тонкостью в спецификациях приведения указателя функции:

Стандарт говорит в [expr.reinterpret.cast] "Указатель функции может быть явно преобразован в указатель на функциюдругой тип. Эффект вызова функции через указатель на тип функции (8.3.5), который отличается от типа, используемого в определении функции, не определен. "

Так что я думаюпрограмма имеет неопределенное поведение.Поскольку вы никогда не вызываете asd как часть правильного выражения, его создавать не нужно.

Clang ++ завершается неудачно так же, как G ++ 4.6, но он работает с G ++ 4.7

(Спасибо Джонатану Уэйкли)

...