#include <string>
#include <type_traits>
struct A {
A(int) {}
};
template<typename... Args>
auto make_A(const Args&... args) -> decltype(A(args...)) {
return A(args...);
}
struct B {
template<typename... Args
//std::enable_if ?
>
B(const Args&... args) : a(args...) { }
A a;
};
int main() {
A a1 = make_a(123);
//A a2 = make_a(std::string("123")); // no make_a<std::string>
B b1(123); // ok
B b2(std::string("123")); // fails because A(std::string) does not exist,
// but should fail already because there is no B(std::string)
}
因此代码A
只能用int
参数来构造。
make_a
使用 SFINAE,因此make_a<Args...>
只有存在时才会实例化A::A(Args...)
。它使用decltype()
返回类型(args
可用)来实现这一点。
是否也可以用B::B<Args...>
类似的方式限制模板构造函数?这里触发 SFINAE 的表达式只能在模板参数中。
在 C++20 中,你可以使用约束和需要表达式来实现这一点:
或者,如果您不想使用 noexcept 说明符,您将无法访问
args
,并且您可以改用std::declval<const Args&>()
: