模板静态功能模板类类型扣除
template static function template class type deduction
我想在单元模板类中发挥静态功能,可以扣除模板类的类型。问题是,从模板类调用静态函数需要明确的类型。我想出的唯一解决方法是模板函数,如果模板成员函数。
这是一个示例。问题是foo4部分不起作用
template <class T>
class Foo
{
private:
Foo() {}
Foo(const Foo&) = delete;
Foo& operator= (const Foo&) = delete;
public:
static auto& Instance()
{
static Foo foo{};
return foo;
}
template<class K> static
auto& DeductInstance(const K&)
{
static Foo<K> foo{};
return foo;
}
};
template<class K>
auto& DeductInstance(const K&)
{
return Foo<K>::Instance();
}
void main()
{
auto& foo1 = Foo<int>::Instance(); //OK
auto& foo2 = Foo<int>::Instance(); //OK (return same example as foo1)
auto& foo3 = DeductInstance(123); //OK
auto& foo4 = Foo::DeductInstance(123); //NOT WORKING
}
使用注入的类名称在理论上是可能的。这将使Foo::
解析为特定的,无关的Foo<x>::
。这是一个例子:
struct BaseFoo {
template<class K> static
auto& DeductInstance(const K&);
};
template <class T>
struct Foo {
static auto& Instance() {
static Foo foo{};
return foo;
}
};
template<>
struct Foo<void> : private BaseFoo {
using BaseFoo::DeductInstance;
};
template<typename K>
auto& BaseFoo::DeductInstance(const K&)
{
return Foo<K>::Instance();
}
using MakeFooAvailable = Foo<void>;
struct Dummy : MakeFooAvailable {
auto& bar() {
// Syntax working
return Foo::DeductInstance(234);
}
};
在Dummy
类中,基本类Foo
的注入类名称,将其解析为Foo<void>
。然后,Foo<void>
正在使BaseFoo::DeductInstance
在其范围中可分辨出来。
我建议不要使用此解决方案,因为它是一个聪明的解决方案。聪明通常意味着令人惊讶。程序员不希望将Foo
视为非模板。我认为最好的解决方案是:
auto& foo1 = Foo<int>::Instance(); //OK
越简单,越好。
是2021,我们有CTAD,但我认为这没有帮助。我认为这与您(和我!)想要的东西非常接近:
// A helper struct to provide Foo with a default template
// that isn't useful for instantiation:
struct DoNotInstantiate { DoNotInstantiate() = delete; };
template <class T = DoNotInstantiate>
class Foo
{
private:
Foo() {
static_assert(!std::is_same_v<T, DoNotInstantiate>, "You can't actually instantiate it with the default, it's just to make the static function work."); // Optional
}
// ...
public:
// ...
template<class K> static
auto& DeductInstance(const K&)
{
static Foo<K> foo{};
return foo;
}
};
因此您可以致电Foo<>::DeduceInstance(bar);
。您仍然必须编写<>
,但否则,我认为这是完美的。
如果您不想要它并且确实希望能够在模板上调用静态,仅命名模板名称,则是:
template <template<typename ...> class FooType, typename T>
auto DeduceInstance(const T& x) {
return FooType<T>::DeduceInstance(x);
}
可以让您调用DeduceInstance<Foo>(x)
,其中Foo
只是一个模板。但这感觉很圆。我更喜欢Foo<>::DeduceInstance(x);
。
如果CTAD让您写
,那将是很好的template <class T>
Foo::DeductInstance(const T&) -> T&;
或可能是
template <class T>
Foo::DeductInstance(const T&) -> Foo<T>::DeduceInstance(const T&);
或类似的内容,基本上说,如果您使用没有类型的模板名称来调用静态,请使用参数列表来涂上呼叫者正在谈论的模板。
我必须承认我不完全理解您要做的事情。但是,您可以做以下两个:
struct foo {
template <typename T>
static T deduce(const T& t) {
return {};
}
};
template <typename T>
T deduce_free(const T& t) {
return {};
}
int main() {
auto x = foo::deduce(1);
auto y = deduce_free(1);
}
但是,在知道T
是什么之前,您无法在bar<T>
的某些实例上调用方法(是否静态)。
c 17的情况有所改变,尽管我知道这适用于构造函数,但,因此您仍然需要foo<int>
,然后才能调用foo<int>::deduce()
我对那说话不错的东西太不经验了;)。
- 错误:在尝试检测 std::cout 是否<< t 时,功能强制转换为数组类型;有效
- 对于非常量指针类型的参数,未调用具有常量指针模板类型参数的功能
- C++从成员类型中扣除类型的功能模板?
- 这种错误的原因是什么:将"功能"重新定义为不同类型的符号
- 模板功能:根据类型名称进行转换
- 如何在同一个模板功能上专门化几种类型?
- 错误:未知类型名称"功能跟踪"
- 我对C 中共享指针列表进行排序的功能未完成类型
- 共享_ptr中多功能数组的类型是什么
- 确定功能主体中的返回类型
- 返回类型不可知模板类成员功能
- 类型推论模板功能返回类型
- C 功能模板指定第二个模板参数类型
- 为什么指定数据类型而不是构造功能参数?C
- C 尝试使用模板输出功能来显示不同类型的数据
- 为什么BOOST :: HANA :: EXAREMIS ::键入实验功能?类型列表的棘手是什么
- 将多种类型传递给STD ::功能C
- C 中此功能的返回类型的含义
- C++ 使用包含不同类型功能对象的基和派生类的 Reactor
- 请求从非标量类型转换为非标量类型(功能)