尝试定义一个函数类型别名,该别名取决于我在其中定义的模板类的参数T。具体来说,如果 T 不是 void,则函数类型的形式为 void foo(T),并且 void foo( )如果无效。
#include <iostream>
#include <type_traits>
#include <functional>
template <typename T>
struct S
{
template <typename U>
using F = std::conditional_t<std::is_void_v<U>, std::function<void()>, std::function<void(U)>>;
F<T> foo;
};
int main()
{
S<int> i;
i.foo = [](int x) { std::cout << "fint " << x << std::endl;};
// i.foo = [](){return;}; // does not compile (good)
i.foo(1);
S<void> v; // ERROR
v.foo = []() {return;};
}
当 T 为 void 时,编译器(使用 C++17)在实例化类时会卡住。
conditional_ftype.cpp: In substitution of ‘template<class T> template<class U> using F = std::conditional_t<is_void_v<U>, std::function<void()>, std::function<void(U)> > [with U = void; T = void]’:
conditional_ftype.cpp:11:10: required from ‘struct S<void>’
conditional_ftype.cpp:22:10: required from here
conditional_ftype.cpp:9:11: error: invalid parameter type ‘void’
9 | using F = std::conditional_t<std::is_void_v<U>, std::function<void()>, std::function<void(U)>>;
| ^
conditional_ftype.cpp:9:11: error: in declaration ‘using F = std::conditional_t<is_void_v<U>, std::function<void()>, std::function<void(U)> >’
专业化可能是最简单的:
template <typename U>
struct function_1
{
using type = void(U);
};
template <>
struct function_1<void>
{
using type = void();
};
template <typename T>
struct S
{
std::function<typename function_1<T>::type> foo;
};