【发布时间】:2020-06-20 05:59:31
【问题描述】:
这里是一个例子:
#include <iostream>
template<typename T,
typename ... Args>
void print(T&& t, Args&& ... args)
{
// line where compilation fails when the A::run is called
if constexpr (std::is_invocable_v<decltype(&T::display),T*,Args...>)
{
t.display(std::forward<Args>(args)...);
}
else
{
std::cout << "not applicable !" << std::endl;
}
}
template<typename T>
class A
{
public:
A(T&& t):t_(t){}
template <typename... Args>
void run(Args&& ... args)
{
print<T,Args...>(t_,std::forward<Args>(args)...);
}
T t_;
};
template <typename T> A(T&) -> A<T&>;
template <typename T> A(T&&) -> A<T>;
class B
{
public:
B(int value):value_(value){}
void display(int a, int b)
{
std::cout << value_ << " "
<< a << " "
<< b << std::endl;
}
int value_;
};
int main()
{
int v1=10;
int v2=20;
B b1{1};
A a1{b1};
a1.t_.display(v1,v2);
A a2{B(2)};
a2.t_.display(v1,v2);
//a1.run(v1,v2); // (1)
//a2.run(v1,v2); // (2)
//a1.run(v1);
return 0;
}
上面的代码编译并运行良好。但如果最后 3 行(对run() 的调用)未注释,则会出现以下编译错误:
(1)
main.cpp:7:48: 错误:‘display’不是‘B&’的成员
if constexpr (std::is_invocable_v<decltype(&T::display),T*,Args...>)
(2)
main.cpp:27:25: error: no matching function for call to ‘print(B&, int&, int&)’
print<T,Args...>(t_,std::forward<Args>(args)...);
注意:
template <typename T> A(T&) -> A<T&>;
template <typename T> A(T&&) -> A<T>;
在这里解释:
c++ copy (reference) constructor and move constructor of class cohabitation
【问题讨论】:
-
std::decay_t工作正常,live demo。 -
@rafix07 我很困惑,这确实为我解决了(2)(c++17):onlinegdb.com/Byx2vo9brU
-
@rafix07 实际上它适用于我的机器 gcc 7.4。我想知道为什么它在 gdb online 上不起作用
标签: c++ template-meta-programming constexpr move-semantics perfect-forwarding