Использование шаблонов не может быть вложено в Visual Studio - PullRequest
0 голосов
/ 01 марта 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<typename F, typename T>
using call_t = decltype(std::declval<F>()(std::declval<T>(), std::declval<T>(), std::declval<T>()));

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

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

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

* call_t от ответ Гийома Рашико , который я хотел использоватьнайти тип возврата.Но я получаю эту ошибку от версии 15.6.7:

error C2064: term does not evaluate to a function taking 3 arguments<br>
note: see reference to alias template instantiation 'call_t<unknown-type,double>' being compiled
note: see reference to function template instantiation 'unknown-type func(const T &)' being compiled

Это прекрасно работает на g ++: https://coliru.stacked -crooked.com / a /48b18b66c39486ef Это будет нормально работать даже на , если я не передам одно using утверждение другому:

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

Есть ли способ, которым яможно обойти это?

1 Ответ

0 голосов
/ 01 марта 2019

Как уже упоминалось @ NathanOliver , правильным решением является обновление до 15.9.5, где это исправлено.Но за исключением того, что вы можете использовать result_of или invoke_result, чтобы решить это на 15.6.7, изменив call_t на:

template<typename F, typename T>
using call_t = result_of_t<F&&(T, T, T)>;

Обратите внимание, что result_of устарела в, поэтому, если вы работаете с "/ std: c ++ 17" или "/ std: c ++ latest", это не сработает, вам нужно использовать более удобный:

template<typename F, typename T>
using call_t = invoke_result_t<F, T, T, T>;

Стоит отметить, что В ответе Гийома Рашико использовался элегантный вердиктный шаблон, который также работает соответственно как: template <typename F, typename... Args> using call_t = result_of_t<F&&(Args&&...)> или template<typename F, typename... Args> using call_t = invoke_result_t<F, Args...>;, если вы измените свое определение func до:

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