Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 类模板实例化中的类型转换_C++_Templates_C++17 - Fatal编程技术网

C++ 类模板实例化中的类型转换

C++ 类模板实例化中的类型转换,c++,templates,c++17,C++,Templates,C++17,我有一个模板类项,它存储各种类型的对象T。它还将属性附加到实例化/初始化中的那些对象 我想实现的一件特殊的事情是,每当项看到一个const char*,它就会将其视为std::string并将其存储。可以这样做,如下所示 但在类型检查中,我发现从const char*实例化的项的类型与从std::string实例化的项的类型仍然不同。请看最后一行,注释为false,我想将其设置为true 这与其说是一个答案,不如说是一个猜测,但我得说不是。模板是在编译时展开的,因为您正在创建 item<c

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

我想实现的一件特殊的事情是,每当项看到一个const char*,它就会将其视为std::string并将其存储。可以这样做,如下所示

但在类型检查中,我发现从const char*实例化的项的类型与从std::string实例化的项的类型仍然不同。请看最后一行,注释为false,我想将其设置为true


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

item<const char*>

item<std::string>
然后扩展的代码看起来像

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


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

这与其说是答案,不如说是猜测。模板是在编译时展开的,因为您正在创建

item<const char*>

item<std::string>
然后扩展的代码看起来像

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


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

好的,我以前从未见过或使用过std::conditional,所以我不确定这是在做什么,但在阅读了它并使用了您的代码之后,我确实通过使用

bar<T>
作为模板类型。所以不是

auto a = item<const char*>("const char *");
auto b = item<string>(string("string"));
是的

问题是,在这两种情况下,您都需要模板类型相同,这意味着在扩展模板之前,该类型需要解析为std::string。只要使用条件,就可以定义任何类型

auto c = item<bar<int>>(5);

我不确定这是一个好的解决方案,这就是为什么我说“工作”,但请看我的另一个答案,关于类类型实际上是不同的。

好的,我以前从未见过或使用过std::conditional,所以我不确定它在做什么,但在阅读了它并使用了您的代码之后,我确实通过使用

bar<T>
作为模板类型。所以不是

auto a = item<const char*>("const char *");
auto b = item<string>(string("string"));
是的

问题是,在这两种情况下,您都需要模板类型相同,这意味着在扩展模板之前,该类型需要解析为std::string。只要使用条件,就可以定义任何类型

auto c = item<bar<int>>(5);

我不确定这是一个好的解决方案,这就是为什么我说“工作”,但我的另一个答案是,类类型实际上是不同的。

不,不能直接使使用不同模板参数的两个模板对象的typeid相同

但要实现最终目标,您可以使用类似工厂的模式。它可能看起来像这样:

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);
} 

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

否,不能直接使使用不同模板参数的两个模板化对象的typeid相同

但要实现最终目标,您可以使用类似工厂的模式。它可能看起来像这样:

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);
} 
这种方法的缺点是,您需要使用此工厂构造所有对象。如果有很多异常,则需要对每个异常进行专门化。

您可以添加:

使用此扣除指南,a将被扣除为项目。

您可以添加:


使用此扣除指南,a将被推断为项目。

为什么您需要相同的typeid?谢谢您的提问。为了进一步的工作。具体地说,我希望有一个模板类容器,其中包含类型相同的T项,并且我希望一个容器可以容纳许多从const char*或std::string初始化的对象。一种解决方法可能是使用类似boost::any的异构容器,但我想看看是否有替代方法。为什么需要相同的typeid?谢谢你的提问。为了进一步的工作。具体地说,我希望有一个模板类容器,其中包含类型相同的T项,并且我希望一个容器可以容纳许多从const char*或std::string初始化的对象。一种解决方法可能是使用类似boost::any的异构容器,但我想看看是否有其他替代方法。谢谢。您的代码应该按预期工作。但我想要的是更改模板类项的设计。main中的代码是由item的用户提供的。谢谢。您的代码应该按预期工作。但我想要的是更改模板类项的设计。main中的代码是由item的用户提供的。我认为这可能是一个解决方案!我会试试的。经过进一步检查,这不起作用。请查看xskxzr的答案。我认为这可能是一个解决方案!我会试试的。经过进一步检查,这不起作用。求你了,切赫
去掉xskxzr的答案。这是最短、最简洁的答案,而且据我所知,它的好处是正确的:案例结束了!非常感谢你。这正是我一直在寻找的!美好的C++11/17中有很多我还不知道的特性!这是最短、最简洁的答案,而且据我所知,它的好处是正确的:案件已结案!非常感谢你。这正是我一直在寻找的!美好的C++11/17中有很多我还不知道的特性!