请求从“const char[]”转换为非标量类型

Conversion from `const char[]` to non-scalar type requested

我正在尝试制作一个 class 将指针包装在另一种类型周围。删除所有无关的位后,它看起来像这样:

template<typename T>
class field {
    std::unique_ptr<T> t_;

public:
    field() : t_(nullptr) {}

    field(const T &t) : t_(std::make_unique<T>(t)) {}

    field<T> &operator=(const T &t) {
        t_.reset(new T(t));
        return *this;
    }
};

我可以通过显式调用它们的构造函数来声明它们,但不能使用 =,像这样:

int main() {
    field<std::string> strA("Hello");
    field<std::string> strB = "Hello";
    return 0;
}

我收到错误

-snip-/StringImplicit/main.cpp: In function ‘int main()’:
-snip-/StringImplicit/main.cpp:21:31: error: conversion from ‘const char [6]’ to non-scalar type ‘field<std::__cxx11::basic_string<char> >’ requested
   21 |     field<std::string> strB = "Hello";
      |                               ^~~~~~~

我哪里错了?如果没有这种转换,我似乎也无法在 class 构造函数中使用 field<std::string>s 和原始字符串,它会引发相同的错误。

编辑:最终目标类似于 discordpp::ApplicationCommandOption option{.type = 3, .name = "message", .description = "The message to echo", .required = true};,其中所有这些参数都是不同类型的字段。

问题是需要两次class类型的转换:

  • const char[6]std::string
  • std::stringfield<std::string>.

有一条规则,隐式转换最多可以有一个 class 类型转换(官方术语是“用户定义”转换,尽管这包括 class 类型,它们是标准库)。

要修复它,您可以使用建议的修复;或手动指定其中一种转换,例如:

auto strB = field<std::string>("Hello");
field<std::string> strC = std::string("Hello");
field<std::string> strD = "Hello"s; 

或者您可以为 const char[] 添加构造函数。

SFINAE 版本的 char 数组构造函数(我相信 C++20 中会有更好的方法):

template<size_t N, typename = std::enable_if_t<std::is_same_v<T, std::string>>>
field(char const (&t)[N])
    : t_(std::make_unique<T>(t)) {}