首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >类模板实例化中的类型转换

类模板实例化中的类型转换
EN

Stack Overflow用户
提问于 2018-09-08 17:44:54
回答 4查看 109关注 0票数 1

我有一个模板类item,它存储各种类型的T对象。它还在实例化/初始化中将属性附加到这些对象。

我想要实现的一件特别的事情是,每当item看到一个const char *,它就把它当作一个std::string来存储。可以这样做,如下所示。

但在类型检查中,我发现从const char *实例化的const char *与从std::string实例化的item的类型仍然不同。请看最后一行注释false,这是我想要做的true

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <string>
#include <type_traits>

using namespace std;

template<typename T>
using bar = typename std::conditional<std::is_same<T, const char *>::value,
                                      string, T>::type;

template<typename T>
class item
{
    bar<T> thing;

    // other attributes ...

public:
    item(T t) : thing(t) {}

    // other constructors ...

    bar<T> what() const
    {
        return thing;
    }
};

int main()
{
    auto a = item("const char *");     // class template argument deduction (C++17)
    auto b = item(string("string"));   // class template argument deduction (C++17)

    cout << std::boolalpha;
    cout << (typeid(a.what()) == typeid(b.what())) << endl; // true
    cout << (typeid(a) == typeid(b)) << endl;               // false
}

我的问题是:是否可以对模板类item item 进行任何更改,以便从 const char * 实例化的 item 与从E 233 std::string**?**实例化的item的类型相同

换句话说,我是否可以对模板类item typeid(a) == typeid(b) 的设计做任何更改,以便typeid(a) == typeid(b)的计算结果为true?

谢谢!

注意:这是之前关于模板函数的https://stackoverflow.com/questions/52235994/type-conversion-in-function-template-deduction的后续。但我认为有一些本质上不同的问题值得提出单独的问题。

编辑:我的目标是更改模板类item (例如item签名)的设计,而不是由用户提供的main中的代码。我希望通过不要求用户在实例化中显式地提供item类型,使T用户的生活更容易。这是指通过C++17模板类、参数演绎或一些等效的解决方法来完成的。

更新:谢谢大家!特别感谢@xskxzr,它的一条线正好解决了我的问题。使用 用户定义的扣减指南 进行类模板参数推导,我甚至不需要在前面的代码中使用技术。我将更新后的代码放在下面进行比较。。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <string>

using namespace std;

template<typename T>
class item
{
    // UPDATE: no bar<T> needed any more
    T thing;

    // other attributes ...

public:
    item(T t) : thing(t) {}

    // other constructors ...

    // UPDATE: no bar<T> needed any more
    T what() const
    {
        return thing;
    }
};

item(const char *) -> item<std::string>;  // UPDATE: user-defined deduction guide !

int main()
{
    auto a = item("const char *");     // class template argument deduction (C++17)
    auto b = item(string("string"));   // class template argument deduction (C++17)

    cout << std::boolalpha;
    cout << (typeid(a.what()) == typeid(b.what())) << endl; // true
    cout << (typeid(a) == typeid(b)) << endl;               // UPDATE: now true !
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-09-08 20:28:51

您可以添加一个用户定义的扣减指南

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
item(const char *) -> item<std::string>;

有了这个演绎指南,a将被推断为item<std::string>

票数 4
EN

Stack Overflow用户

发布于 2018-09-08 20:14:05

不,您不能直接使用不同的模板论证使两个模板对象的类型相同。

但是为了达到你的最终目标,你可以使用类似于工厂的模式。它可能看起来像这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template<typename T, typename R = T>
item<R> make_item(T&& t)
{
    return item<T>(std::forward<T>(t));
}

// Specialization for const char *
template<>
item<std::string> make_item(const char *&& str)
{
    return item<std::string>(str);
} 

这种方法的缺点是您需要用这个工厂来构造所有的对象。如果有很多异常,则需要对每个异常进行专门化处理。

票数 1
EN

Stack Overflow用户

发布于 2018-09-08 18:08:47

这与其说是答案,不如说是猜测,但我会说不。模板在编译时展开,因此因为您要创建一个

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
item<const char*>

和一个

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
item<std::string>

然后展开的代码看起来如下所示

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class item1
{
    bar<const char*> thing;

    // other attributes ...

public:
    item(const char* t) : thing(t) {}

    // other constructors ...

    bar<const char*> what() const
    {
        return thing;
    }
};


class item2
{
    bar<std::string> thing;

    // other attributes ...

public:
    item(std::string t) : thing(t) {}

    // other constructors ...

    bar<std::string> what() const
    {
        return thing;
    }
};

(或多或少;它们实际上不会被称为item1和item2)

如何计算这两种类型取决于您,但对于编译器来说,它们实际上是两种不同的类型。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52240679

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文