ошибка компоновщика с шаблонной функцией-другом шаблонного класса при использовании независимого от шаблона enable_if - PullRequest
0 голосов
/ 13 февраля 2019

Я имею дело с шаблонным классом с функцией шаблонного друга.

template<typename T>
struct X {
  template<typename someX>
  auto friend f (someX x) -> std::enable_if_t<std::is_same_v<decltype(x.hidden), int>, int>;

private:
  T hidden = 42;
};

template<typename someX>
auto f(someX x) -> std::enable_if_t<std::is_same_v<decltype(x.hidden), int>, int> {return x.hidden;}

это прекрасно компилируется с g ++, но завершается ошибкой во время соединения в

int main () {
  X<int> x;
  std::cout << f(x);
}

с

prog.cc:(.text+0x15): undefined reference to `std::enable_if<is_same_v<decltype ({parm#1}.hidden), int>, int>::type f<X<int> >(X<int>)'
collect2: error: ld returned 1 exit status

см. Здесь .

Я наблюдал следующее:

  • при замене второго аргумента enable_if (тип) чем-то, что зависит от шаблона класса (intdecltype(x.hidden)) см. здесь соединение успешно выполняется с помощью g ++.

  • при открытии hidden иесли удалить объявление друга, то код прекрасно связывается (поэтому создается экземпляр шаблона функции).

  • , удаление enable_if и просто объявление типа возвращаемого значения как int работает нормально.

  • переместить enable_if из возвращаемого типа в template <typename … , typename = typename enable_if_t<…>>, но здесь мне не удается скомпилировать, потому что g ++ и clang ++ говорят мне, что объявления друзей не допускают аргументы шаблона по умолчанию.

  • удалите enable_if из объявления друга и сохраните его только в определенномiton → не может связать

  • , когда компиляция с использованием clang ++ успешно завершается

  • переместить определение функции в объявление класса (в примере с реальным миром происходит сбой, потому что функция должна принимать различные аргументы в качестве шаблона переменной, а затем я нарушаю правило одного определения, определяя f(X<int>, X<float>) один раз в определении X<int> и один раз в X<float> определение.

Это ошибка g ++ (8.2) или clang ++ нарушает стандарт, и в последнем случае как мне запустить генерацию кода для функции?

1 Ответ

0 голосов
/ 13 февраля 2019

это ошибка g ++ (8.2) или clang ++ нарушает стандарт

Я подозреваю, что gcc верен.Друзья шаблона - это темный угол языка.

как мне запустить генерацию кода для функции?

Я бы сделал это через подружившегося актера.

#include <iostream>

struct friend_of_f
{
    template<class someX> 
    static auto apply(someX x) -> std::enable_if_t<std::is_same_v<decltype(x.hidden), int>, decltype(x.hidden)>
    {
        return x.hidden;
    }
};

template<typename someX>
auto f(someX x) -> decltype(friend_of_f::apply(x))
{
    return friend_of_f::apply(x);
}

template<typename T>
struct X 
{

friend friend_of_f;

private:
  T hidden = 42;
};




int main () {
  X<int> x;
  std::cout << f(x);
  X<double> y;
//  std::cout << f(y);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...