Использование шаблонов Невозможно выбрать функции шаблона для использования в качестве параметров в Visual Studio - PullRequest
0 голосов
/ 07 марта 2019

Это примерно так же просто, как я мог бы сделать игрушечный пример, который все еще попал в ошибку:

struct Vector3f64 {
  double x;
  double y;
  double z;
};

struct Vector3f32 {
  float x;
  float y;
  float z;
};

// I use this to select their element type in functions:
template <typename T>
using param_vector = std::conditional_t<std::is_same_v<std::remove_const_t<std::remove_reference_t<T>>, Vector3f64>, double, float>;

// This is the function I want to pull the return type from:
template <typename T>
T VectorVolume(const T x, const T y, const T z) {
  return x * x + y * y + z * z;
}

template<class R, class... ARGS>
std::function<R(ARGS...)> make_func(R(*ptr)(ARGS...)) {
  return std::function<R(ARGS...)>(ptr);
}

// This function fails to compile:
template <typename T>
typename decltype(make_func(&VectorVolume<param_vector<T>>))::result_type func(const T& dir) {
  return VectorVolume(dir.x, dir.y, dir.z);
}

int main() {
  const Vector3f64 foo{ 10.0, 10.0, 10.0 };

  std::cout << func(foo) << std::endl;
}

make_func от ответа SergyA , который я хотел создатьstd::function чтобы я мог найти тип возврата без явного объявления параметров VectorVolume.Но я получаю эту ошибку от версия 15.6.7:

ошибка C2039: result_type: не является членом ошибки 'global namespace' C2061:синтаксическая ошибка: идентификатор func ошибка C2143: синтаксическая ошибка: отсутствует ; до { ошибка C2447: {: отсутствует заголовок функции (формальный список старого стиля?) ошибка C3861: func: идентификатор не найден

Это прекрасно работает на в g ++: https://ideone.com/PU3oBV Это будет отлично работать даже на , еслиЯ не передаю оператор using в качестве параметра шаблона:

template <typename T>
typename decltype(make_func(&VectorVolume<double>))::result_type func(const T& dir) {
    return VectorVolume(dir.x, dir.y, dir.z);
}

Это почти идентично проблеме, с которой я работал здесь: Использование шаблонов не может быть вложено в Visual Studio К сожалению, в этом случае я мог бы просто заменить конструкцию моей функции на вызов result_of.В этом случае я просто не вижу, как я могу изменить make_func, чтобы обойти эту ошибку.Кто-нибудь знает об обходном пути?(За исключением обновления до 15.9.5, которое решает эту проблему.)

Ответы [ 2 ]

1 голос
/ 07 марта 2019

В качестве обходного пути вы можете просто сделать:

template <typename T>
auto func(const T& dir)
-> decltype(VectorVolume(dir.x, dir.y, dir.z))
{
    return VectorVolume(dir.x, dir.y, dir.z);
}
0 голосов
/ 07 марта 2019

Вы действительно интересуетесь только function::result_type, так что на самом деле нет необходимости проходить ошибочный путь возврата function. Просто верните тип результата и выполните для него decltype (вам даже не нужно определять функцию, поскольку вы на самом деле ее не вызываете.) Примерно так:

template <typename R, typename... ARGS>
R make_func(R(*)(ARGS...));

Тогда просто используйте тип возврата:

template <typename T>
decltype(make_func(&VectorVolume<param_vector<T>>)) func(const T& dir) {
    return VectorVolume(dir.x, dir.y, dir.z);
}

Это прекрасно работает на Visual Studio 15.6.7 и в качестве дополнительного бонуса полностью совместимо : https://ideone.com/gcYo8x

...