J'ai une classe de modèle simplestring qui gère simplement TChar * et sa longueur. TChar peut être à la fois char et wchar_t. Voici une méthode simple de découpage à gauche,

simplestring<T> ltrim(const T* _s = nullptr) const
{
    const T* s = _s;
    if (s == nullptr)
    {
#if ( sizeof(T) == 1)
        s = " \t\r\n";
#else
        s = L" \t\r\n";
#endif
    }
    constexpr int len = tstrlen(s);
    find_first_not_of(s, len);
}

Je veux que s reçoive un caractère * lorsque T est un caractère et sinon un wchar_t *. Il ne compile pas. PS: Mon projet prend en charge C ++ 17.

1
Zhang 9 mai 2020 à 10:05

4 réponses

Meilleure réponse

En C ++ 17, vous pouvez utiliser if constexpr:

if constexpr (sizeof(T) == 1) // or (std::is_same_v<T, char>)
    s = " \t\r\n";
else
    s = L" \t\r\n";
1
Evg 9 mai 2020 à 07:42

Avec C ++ 14, les Modèles de variables ont été introduit.

Ainsi, en utilisant la spécialisation de modèle, il est possible de fournir une variable avec le même nom mais des valeurs différentes pour différents types.

Pour illustrer une solution possible, j'ai réalisé le MCVE suivant:

#include <iostream>

template <typename T>
constexpr const T *init;

template <>
constexpr const char *init<char> = "string";

template <>
constexpr const wchar_t *init<wchar_t> = L"wstring";

template <typename T>
struct simplestring {
  const T *str;
  simplestring(const T *str = init<T>): str(str) { }
};

int main()
{
  simplestring<char> str;
  std::cout << "str: " << str.str << '\n';
  simplestring<wchar_t> wStr;
  std::wcout << "wStr: " << wStr.str << '\n';
}

Production:

str: string
wStr: wstring

Démo en direct sur coliru


Le modèle de variable en tant que static const membre de template class simplestring:

#include <iostream>

template <typename T>
struct simplestring {
  static const T *init;
  const T *str;
  simplestring(const T *str = init): str(str) { }
};

template <>
const char *simplestring<char>::init = "string";

template <>
const wchar_t *simplestring<wchar_t>::init = L"wstring";

int main()
{
  simplestring<char> str;
  std::cout << "str: " << str.str << '\n';
  simplestring<wchar_t> wStr;
  std::wcout << "wStr: " << wStr.str << '\n';
}

Production:

str: string
wStr: wstring

Démo de la vie sur coliru

1
Scheff 9 mai 2020 à 08:13

Réponses combinées de Scheff et Evg, j'ai fait celle-ci,

template<typename T>
struct simplestring
{
    static const T *default_trim;// = nullptr;

public:
    typedef std::basic_string<T> tstring;
    T* str = nullptr;
    unsigned int length = 0;

    void trim()
    {
        if constexpr(std::is_same<T, char>::value)
        {
            cout << "char";
            cout << default_trim;
        }
        else
        {
            cout << "wchar_t";
            wcout << default_trim;
        }
    }
};

template<>
const char* simplestring<char>::default_trim = "hello \t\r\n";
template<>
const wchar_t* simplestring<wchar_t>::default_trim = L"hello \t\r\n";

void test()
{
    simplestring<char> s;
    s.trim();
    simplestring<wchar_t> s2;
    s2.trim();
}

Merci à eux!

1
Zhang 9 mai 2020 à 08:43

Encore une autre option:

template<typename CharT> foo(CharT const* &r);

template<> foo(char const *&r) { r = " \t\r\n"; }
template<> foo(wchar_t const *&r) { r = L" \t\r\n"; }
1
M.M 9 mai 2020 à 09:09