Сообщите массиву const char, который не заканчивается на '\ 0', кроме строки в стиле C во время компиляции - PullRequest
2 голосов
/ 14 июля 2020

Можно ли указать массив const char, который не заканчивается на '\0', отдельно от строки в стиле C во время компиляции?

Скажем, я хочу написать два конструктора для класса.

Один конструктор строит из строки в стиле C, которая заканчивается на '\0'.

Другой конструктор с другим поведением создает из массива const char, который не заканчивается на '\0'.

В качестве минимального примера рассмотрим

#include <cstddef>
#include <iostream>

struct Foo
{
    Foo(const char *)
    {
        std::cout << "a C-style string" << std::endl;
    }

    // Question: How to modify Foo so that a const char array that does not
    //           ends with '\0' will go to a different constructor?
    template<size_t N>
    Foo(const char (&)[N])
    {
        std::cout << "a const char array "
                     "that does not ends with '\\0'" << std::endl;
    }
};

int main()
{
    Foo("a C-style string");          // print "a C-style string"

    const char a[3] {'a', 'b', 'c'};
    Foo foo(a);                       // print "a C-style string" - can it change?

    return 0;
}

Скомпилировано с помощью g++ -std=c++17.

Вопрос: Есть ли способ достичь этого?

Возможно, я мог бы применить методы SFINAE, но я не понял, как это сделать.

Примечание. В настоящее время есть несколько похожих, но не идентичных вопросов по StackOverflow. Я не нашел ни одного, который прямо отвечает на мой вопрос.

Ответы [ 2 ]

2 голосов
/ 14 июля 2020

Нет, это невозможно. При разрешении перегрузки предпочтительнее использовать нешаблонные функции. Разрешение перегрузки шаблонных функций C ++

Нестандартные функции - первоклассные граждане.

Почему происходит перегрузка шаблонных и не шаблонных функций с «той же сигнатурой» вызвать нешаблонную функцию?

Когда и шаблонная функция, и нешаблонная функция являются жизнеспособными для разрешения вызова функции, нешаблонная функция является выбрано.

Возможное решение:

struct Foo
{
    void Cstr(const char *)
    {
        std::cout << "a C-style string" << std::endl;
    }

    template<size_t N>
    Foo(const char (&s)[N])
    {
        if (N > 0 && !s[N - 1])
            Cstr(s);
        else
            std::cout << "a const char array "
                         "that does not ends with '\\0'" << std::endl;
    }
};
1 голос
/ 14 июля 2020

Интересно то, что при удалении const в объявлении массива он идет с конструктором массива

#include <cstddef>
#include <iostream>

struct Foo
{
    Foo(const char *)
    {
        std::cout << "a C-style string" << std::endl;
    }

    template<size_t N>
    Foo(const char (&)[N])
    {
        std::cout << "a const char array "
                     "that does not ends with '\0'" << std::endl;
    }
};

int main()
{
    Foo("a C-style string");

    // const char a[3] {'a', 'b', 'c'};
    char a[3] {'a', 'b', 'c'};
    Foo foo(a);

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...