简体   繁体   English

如何在不假设任何构造函数的情况下获取构造函数和取消引用运算符(decltype)的类型?

[英]How to get the type of constructor and dereference operator (decltype) without assuming any constructor?

Assume I have the following template:假设我有以下模板:

template<typename T>
struct S
{
    typedef decltype(foo(T{})) TypeThatSomeFooFunctionReturns;
    typedef decltype(*TypeThatSomeFooFunctionReturns{}) TypeOfDereferenceOfWhateverFooReturns;
    ...
};

Now, this works just fine if the type T has a default constructor and if whatever "foo(T)" returns also has a default constructor.现在,如果类型 T 有一个默认构造函数并且如果任何 "foo(T)" 返回的也有一个默认构造函数,那么这很好用。

But how would I write the template, if I don't want that assumption but also support any type T regardless of whether it (or any "foo(T)") provides constructors?但是,如果我不希望这种假设但也支持任何类型 T,无论它(或任何“foo(T)”)是否提供构造函数,我将如何编写模板? (As I never construct these objects by myself anyway) (因为我从来没有自己构建这些对象)

One clumsy solution that springs into my mind is to force the users of struct S to provide a template specialization for its arguments, basically unrolling the work of finding the correct type to whoever uses S:我想到的一个笨拙的解决方案是强制 struct S 的用户为其 arguments 提供模板专业化,基本上将寻找正确类型的工作展开给使用 S 的人:

template<typename T> struct S_Def { };
// User needs to provide these for each type
template<> struct S_Def<MyType> { typedef int* ReturnOfFoo; typedef int& DerefOfReturnOfFoo; };

template<typename T>
struct S
{
    typedef S_Def<T>::ReturnOfFoo TypeThatSomeFooFunctionReturns;
    typedef S_Def<T>::DerefOfReturnOfFoo TypeOfDereferenceOfWhateverFooReturns;
    ...
};

I'd like to avoid that burden.我想避免这种负担。

Is there any other way to tell the compiler to just take whatever type any reachable function "foo(T)" returns for the typedef and then whatever any dereference operator on that type would return?有没有其他方法可以告诉编译器只采用任何可到达的 function "foo(T)" 返回的 typedef 类型,然后该类型的任何取消引用运算符将返回?

If not, are there reasons why?如果不是,有什么原因吗? (Is it impossible? I'd be fine if ambiguity lead to a compile error.. Or too hard for the compiler to find?) (这是不可能的吗?如果歧义导致编译错误我会很好。或者编译器很难找到?)

Thanks, Imi.谢谢,伊米。

You might use std::declval , and type_traits to modify the type:您可以使用std::declval和 type_traits 来修改类型:

template<typename T>
struct S
{
    using TypeThatSomeFooFunctionReturns = decltype(foo(std::declval<T>()));
    using TypeOfDereferenceOfWhateverFooReturns =
       std::remove_pointer_t<decltype(foo(std::declval<T>()))>;
    // ...
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM