简体   繁体   English

字符串 class 构造函数接受 const char* 列表

[英]String class constructor accepting list of const char*

In my String class, I want to make a ctor that accept variable length of arguments ( const char* ) like parameter pack with variadic template.在我的字符串 class 中,我想制作一个接受可变长度 arguments ( const char* ) 的 ctor,例如带有可变参数模板的参数包。

Something like following像下面这样的东西

class String
{
public: 
    
    String(const char*... xList)
    {
         // Internally appending all const char* present in xList and 
         // populating String class char buffer
    } 

};

Any idea how to achieve this?知道如何实现这一目标吗? I was under impression that following thing should work... but it is not.我的印象是,以下事情应该可以工作……但事实并非如此。

template <const char* ... Args>
String(Args... xList)
{
    
} 

There may be a way by using va_arg but I am not interested in that.可能有一种使用va_arg的方法,但我对此不感兴趣。

The way to achieve what you want is to take arguments of arbitrary types and then to constrain them using SFINAE .实现您想要的方法是采用任意类型的 arguments ,然后使用SFINAE约束它们。 In C++11/14, you'll need some additional boilerplate code:在 C++11/14 中,您需要一些额外的样板代码:

template<class...>
struct conjunction : std::true_type {};

template<class B>
struct conjunction<B> : B {};

template<class B, class... Bn>
struct conjunction<B, Bn...> 
    : std::conditional_t<B::value, conjunction<Bn...>, B> {};

class String
{
public: 
    template<class... Args, typename = std::enable_if_t<
        conjunction<std::is_convertible<Args, const char*>...>::value>>
    String(const Args&... list)
    {} 
};

In C++17, the solution is shorter:在 C++17 中,解决方案更短:

class String
{
public: 
    template<class... Args, typename = std::enable_if_t<
        (std::is_convertible_v<Args, const char*> && ...)>>
    String(const Args&... list)
    {} 
};

Here is a working example using variadic templates and SFINAE which won't compile if you don't provide const char* s这是一个使用可变参数模板和SFINAE的工作示例,如果您不提供const char* s,它将无法编译

#include <type_traits>
#include <list>
#include <iostream>

struct String
{
    std::list<char> ls;
    template<class ... Args, class = std::enable_if_t<std::is_same_v<std::common_type_t<Args...>, const char *>>>
    String(Args...args):ls{*args...}
    {
    }

};

int main(){
    auto c1 = 'a'; const char * pc1 = &c1;
    auto c2 = 'b'; const char * pc2 = &c2;
    auto c3 = 'c'; const char * pc3 = &c3;
    String s{pc1, pc2, pc3};

    for(auto it = s.ls.begin();it != s.ls.end(); ++it)std::cout << *it;
}

Live居住

With c++11 , the code can be like this使用c++11 ,代码可以是这样的

#include <type_traits>
#include <list>
#include <iostream>

struct String
{
    std::list<char> ls;

    template<class ... Args, class = typename std::enable_if<std::is_same<typename std::common_type<Args...>::type, const char *>::value>::type>
    String(Args...args):ls{*args...}
    {
    }

};

int main(){
    auto c1 = 'a'; const char * pc1 = &c1;
    auto c2 = 'b'; const char * pc2 = &c2;
    auto c3 = 'c'; const char * pc3 = &c3;
    String s{pc1, pc2, pc3};

    for(auto it = s.ls.begin();it != s.ls.end(); ++it)std::cout << *it;
}

Live居住

Not exactly what you asked but... if you accept an additional couple of brackets calling the constructor, you can pass your variadic list of char const * as follows不完全是你问的,但是......如果你接受额外的几个括号调用构造函数,你可以传递你的char const *的可变参数列表,如下所示

struct foo
 {
   template <std::size_t Dim>
   foo (char const * const (&arr)[Dim])
    { /* do something with arr */ }
 };

The drawback is that you can't call it as follows缺点是不能如下调用

foo f("one", "two", "three");

but you have to add the brackets但你必须添加括号

// ...V.....................V
foo f({"one", "two", "three"});

The following is a full compiling example下面是一个完整的编译示例

#include <iostream>

struct foo
 {
   template <std::size_t Dim>
   foo (char const * const (&arr)[Dim])
    {
      for ( auto const & str : arr )
         std::cout << str << std::endl;
    } 
};

int main ()
 { 
   foo f({"one", "two", "three"});
 }

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

相关问题 String(const char*) 构造函数 memory 泄漏字符串 class - String(const char*) constructor memory leak in string class 使用字符串中的构造函数从 const char[] 转换为 class - Conversion from const char[] to class with constructor from string 使用std :: string构造函数复制const char * - Copy of const char * using std::string constructor 从 initializer_list 转换<const char*>初始化器列表<string>在向量构造函数中</string></const> - Conversion from initializer_list<const char*> to initializer_list<string> in vector constructor const char *在构造函数中的用法 - const char* usage in constructor 当该类具有const char *构造函数时,为什么用const char *变量构造该类的未分配临时实例,为什么会出错? - Why is it an error to construct an unassigned temporary instance of a class with a const char* variable when that class has a const char* constructor? const char *自定义String类的区别 - const char* difference in custom String class 将字符串复制到类中的const char - Copy string to const char inside a class 无法将 const char 字符串传递给模板 class - Cannot pass a const char string to a template class 为类成员返回const std :: string&vs const char * - Returning const std::string& vs const char* for class member
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM