【问题标题】:How to properly apply decltype together with SFINAE?如何正确应用 decltype 和 SFINAE?
【发布时间】:2021-08-27 05:03:43
【问题描述】:

我编写了一个模板包装器,它应该找出类是否拥有该函数。

template<typename...>
using void_t = void;

template <typename ,typename = void>
struct has_member:std::false_type{};

template<typename T>
struct has_member<T, void_t<decltype(std::declval<T>().push_back())>>:std::true_type{};

但我不知道如何正确应用它。我一开始是这样尝试的:

template<typename T, bool = has_member<T>::value>
void foo(T& container) {
    std::cout << "i here";
}

但一切都在那里,即即使没有 push_back 功能:

std::set<int> st;
foo(st); // okey

尝试更改为:

template<typename T,typename std::enable_if_t< has_member<T>::value ,int>* = nullptr >
void foo(T& container) {
    std::cout << "i here";
}

但是加上这样的函数调用

std::vector<int> vc(10);
foo(vc);

我收到一些错误:

Error (active)  E0304   no instance of function template "foo" matches the argument list    
Error   C2672   'foo': no matching overloaded function found    
Error   C2783   'void foo(T &)': could not deduce template argument for '__formal'  

我很乐意帮助找出我做错了什么。

还有。 所有结构都可以替换吗?

template<typename T>
using has_type = decltype(std::declval<T>().push_back());

我也没有在函数中插入(与上面相同的错误)

【问题讨论】:

  • 但是我得到了一些错误:这是预期的行为。你期待什么行为?
  • @songyuanyao 我在那里用了一个向量,希望它会通过
  • 没有没有函数参数的std::vector::push_back()重载。
  • 除了答案中的问题外,foo 上没有 SFINAE,您要么需要根据 has_member 的值对其进行专门化,要么实际对其应用 SFINAE。目前它只获得一个bool 参数,即truefalse
  • @463035818_is_not_a_number 好的,谢谢

标签: c++ templates sfinae decltype


【解决方案1】:

我在那里使用了一个向量,并希望它会通过

问题出在std::declval&lt;T&gt;().push_back(),没有push_backstd::vector 采取任何措施。

您需要将参数传递给push_back,例如

template<typename T>
struct has_member<T, void_t<decltype(std::declval<T>().push_back(std::declval<typename T::value_type>()))>>:std::true_type{};

LIVE

关于为什么第一个解决方案不起作用,因为当has_member&lt;T&gt;::valuetrue 时,实例化foo&lt;T, true&gt; 被调用,否则foo&lt;T, false&gt; 被调用,两者都是有效的。

【讨论】:

  • 确实,我什至认为您不需要考虑参数。感谢您的帮助!
猜你喜欢
  • 2013-07-10
  • 1970-01-01
  • 1970-01-01
  • 2017-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-15
  • 1970-01-01
相关资源
最近更新 更多