繁体   English   中英

使用decltype的函数参数类型

[英]Function parameter type using decltype

注意:此问题中提供的示例不是生产代码,根本没有任何意义。 它只是在那里说明我的问题。

我正在测试decltype的可能性,特别是如果它用于推断函数参数类型,并遇到了问题:

假设有两个类结构如下:

struct ClassInt
{
    // Note: no default ctor
    ClassInt(int value)
        :   m_Value(value)
    {}

    int  m_Value;
};

struct ClassDouble
{
    // Note: no default ctor
    ClassDouble(double value)
        :   m_Value(value)
    {}

    double  m_Value;
};

现在,我写了一个函数(以某种方式)通过字符串检索一个type参数的实例(应该是上面的一个)并将一个给定的值赋给它的m_Value成员:

template< typename Ty >
Ty* get_fake_ptr() { return nullptr; }


// Retrieve pointer to Ty object by name and assign its value member.
// The problem is that we don't actually have an instance of Ty at the point
// where we want to define the type of the parameter "value".
template< typename Ty >
void assign(std::string name, decltype(get_fake_ptr<Ty>()->m_Value) value)
{
    // Somehow get pointer to a Ty object by name
    Ty* obj = ????;

    // Assign
    obj->m_Value = value;
}

现在,参数value的类型取决于类型参数,因为使用的类在成员m_Value的类型上不同。 如您所见,我使用decltype解决了它。 现在,通常,您将在参数上使用decltype ,如下所示:

template<typename Ty>
void assign(Ty& obj, decltype(obj.m_Value) value);

但这显然不可能在这里,因为在函数体中检索实际实例,因此在声明函数参数的位置不可用。

我通过使用模板函数get_fake_ptr一起攻击它, get_fake_ptr返回匹配类型的nullptr ,所以我有一个“伪实例”,编译器可以使用它来确定成员类型。 它有效:

工作的

现在,正如我所说的那样,这对我来说似乎真的很烦人。 所以:

有没有更好的方法来解决这个问题?

谢谢!

我认为这种方法没有错。

在模板元编程方面,这些“黑客”是课程的标准。

不过,我可以建议一种略有不同的设计模式。 像这样的东西:

struct ClassInt
{
    // Note: no default ctor
    ClassInt(int value)
        :   m_Value(value)
    {}

    typedef int m_value_t;

    m_value_t  m_Value;
};

struct ClassDouble
{
    // Note: no default ctor
    ClassDouble(double value)
        :   m_Value(value)
    {}

    typedef double m_value_t;

    m_value_t  m_Value;
};

// ...
template< typename Ty >
void assign(std::string name, typename Ty::value_t value)
{
    // Somehow get pointer to a Ty object by name
    Ty* obj = ????;

    // Assign
    obj->m_Value = value;
}

您可以使用decltype(std::declval<T>().m_Value)来推断Tm_Value成员的类型,而不是使用get_fake_ptr()函数。 他们最终实现了类似的目标。

顺便说一下,你的get_fake_ptr()函数不需要定义。 您可以简单地将其保留为template <typename T> T* get_fake_ptr(); 你仍然可以在decltype使用它。

另一种方法是添加另一个模板参数,让分配处理匹配的类型和转换。 任何不可转换的值类型都将生成编译错误。

template<typename Ty, typename VALUE_TYPE>
void assign(std::string name, VALUE_TYPE value) {
  Ty* obj = ???
  obj->m_Value = value;
}

暂无
暂无

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

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