Передача строкового литерала в качестве параметра к шаблонному классу C++

Здесь нет ничего неожиданного. Как объяснено в Как работает HashPartitioner? Spark использует хэш (ключ) по модулю количества разделов и неравномерное распределение, особенно для небольших наборов данных, не является неожиданным.

Ожидается также разница между Dataset и RDD, так как оба используют разные функции хеширования (то же самое).

Наконец,

В результате scala / spark генерирует неожиданный результат и создает меньше разделов

blockquote>

- это не правильное наблюдение. Количество созданных разделов является точно запрошенным

scala> dfMyDataRepartitioned.rdd.getNumPartitions
res8: Int = 5

, но пустые не будут видны в агрегации, потому что нет соответствующих значений.

39
задан Mawg 5 December 2017 в 19:25
поделиться

7 ответов

[

] К сожалению, в настоящее время C++ не поддерживает использование строковых литералов (или реальных литералов) в качестве параметров шаблона.[

] [

] Но перечитывая ваш вопрос, это то, что вы спрашиваете? Вы не можете сказать:[

] [
foo <"bar"> x;
] [

]но можете сказать[

] [
template <typename T>
struct foo {
   foo( T t ) {}
};

foo <const char *> f( "bar" );
]
21
ответ дан 27 November 2019 в 02:07
поделиться

C++ 20 fixed_string + "Типы классов в Шаблонных Параметрах Нетипа"

, По-видимому, предложение по этому было сначала принято, но затем удалено: "Строковые литералы как шаблонные параметры нетипа"

удаление состояло частично в том, потому что это, как считали, было достаточно легко сделать с другим предложением, которое было принято: "Типы классов в Шаблонных Параметрах Нетипа" .

принятое предложение содержит пример со следующим синтаксисом:

template <std::basic_fixed_string Str>
struct A {};
using hello_A = A<"hello">;

я попытаюсь обновить это с примером, который на самом деле говорит мне что-либо, после того как я вижу компилятор, который поддерживает его.

Redditor А также показал что следующие компиляции на ведущем устройстве GCC: https://godbolt.org/z/L0J2K2

template<unsigned N>
struct FixedString {
    char buf[N + 1]{};
    constexpr FixedString(char const* s) {
        for (unsigned i = 0; i != N; ++i) buf[i] = s[i];
    }
    constexpr operator char const*() const { return buf; }
};
template<unsigned N> FixedString(char const (&)[N]) -> FixedString<N - 1>;

template<FixedString T>
class Foo {
    static constexpr char const* Name = T;
public:
    void hello() const;
};

int main() {
    Foo<"Hello!"> foo;
    foo.hello();
}

g++ -std=c++2a 9.2.1 от Ubuntu PPA не удается скомпилировать это с:

/tmp/ccZPAqRi.o: In function `main':
main.cpp:(.text+0x1f): undefined reference to `_ZNK3FooIXtl11FixedStringILj6EEtlA7_cLc72ELc101ELc108ELc108ELc111ELc33EEEEE5helloEv'
collect2: error: ld returned 1 exit status

Библиография: https://botondballo.wordpress.com/2018/03/28/trip-report-c-standards-meeting-in-jacksonville-march-2018 /

Наконец, EWG решила вытянуть ранее утвержденное предложение позволить строковые литералы в шаблонных параметрах нетипа, потому что более общее средство для разрешения типов классов в нетипе обрабатывает параметры по шаблону (который был просто утвержден), достаточно хорошая замена. (Это - изменение от последней встречи, когда казалось, что мы захотим обоих.) Основное различие - то, что теперь необходимо перенестись символьный массив в структуру (думайте fixed_string или подобный), и использование, что как шаблонный тип параметра. (Пользовательская литеральная часть P0424 все еще продвигается с соответствующей корректировкой позволенных шаблонных типов параметра.)

Это будет особенно прохладно с C++ 17 if constexpr: , если / еще во время компиляции в C++?

Этот вид функции, кажется, соответствует потрясающему "constexpr все" предложения, которые вошли в C++ 20, такой как: это возможный использовать станд.:: строка в constexpr?

0
ответ дан 27 November 2019 в 02:07
поделиться
[

]Далее от ответа Нила: один из способов использования строк с шаблонами по вашему желанию - это определить класс трейтов и определить строку как трейт типа. [

] [
#include <iostream>

template <class T>
struct MyTypeTraits
{
   static const char* name;
};

template <class T>
const char* MyTypeTraits<T>::name = "Hello";

template <>
struct MyTypeTraits<int>
{
   static const char* name;
};

const char* MyTypeTraits<int>::name = "Hello int";

template <class T>
class MyTemplateClass
{
    public:
     void print() {
         std::cout << "My name is: " << MyTypeTraits<T>::name << std::endl;
     }
};

int main()
{
     MyTemplateClass<int>().print();
     MyTemplateClass<char>().print();
}
] [

] печатает [

] [
My name is: Hello int
My name is: Hello
]
37
ответ дан 27 November 2019 в 02:07
поделиться
[
] [

]Мне нужен класс, который принимает в конструкторе два параметра. Первый может быть либо int, либо double, либо float, так что, а второй всегда строковый литерал "моя строка"[

] [
] [
template<typename T>
class demo
{
   T data;
   std::string s;

   public:

   demo(T d,std::string x="my string"):data(d),s(x) //Your constructor
   {
   }
};
] [

]Я не уверен, но это то, что вы хотите?[

].
3
ответ дан 27 November 2019 в 02:07
поделиться
[
] [

] строковый литерал "моя строка", так что, полагаю, const char * const[

] [
] [

]На самом деле, строковые литералы с n видимыми символами имеют тип []const char[n+1][]. [

] [
#include <iostream>
#include <typeinfo>

template<class T>
void test(const T& t)
{
    std::cout << typeid(t).name() << std::endl;
}

int main()
{
    test("hello world"); // prints A12_c on my compiler
}
]
2
ответ дан 27 November 2019 в 02:07
поделиться
[

]EDIT: ok Заголовок вашего вопроса кажется вводящим в заблуждение[

] [
] [

] "Мне нужен класс, который принимает два параметра в своем конструкторе. Первый может быть либо int, либо double, либо float, так что, а второй всегда строковый литерал "моя строка", так что я думаю const char * const."[

] [
] [

]Похоже, что вы пытаетесь достичь:[

] [
template<typename T>
class Foo
{
  public:
  Foo(T t,  const char* s) : first(t), second(s)
  {
    // do something
  }

  private:
  T first;
  const char* second;

};
] [

]Это сработает для любого типа, для первого параметра: []int[], []float[], []double[], неважно.[

] [

]Теперь, если вы действительно хотите ограничить тип первого параметра только []int[], []float[] или []double[]; вы можете придумать что-нибудь более сложное, например[

] [
template<typename T>
struct RestrictType;

template<>
struct RestrictType<int>
{
  typedef int Type;
};

template<>
struct RestrictType<float>
{
  typedef float Type;
};

template<>
struct RestrictType<double>
{
  typedef double Type;
};

template<typename T>
class Foo
{
  typedef typename RestrictType<T>::Type FirstType;

  public:
  Foo(FirstType t,  const char* s) : first(t), second(s)
  {
    // do something
  }

  private:
  FirstType first;
  const char* second;

};

int main()
{
  Foo<int> f1(0, "can");
  Foo<float> f2(1, "i");
  Foo<double> f3(1, "have");
  //Foo<char> f4(0, "a pony?");
}
] [

]Если вы удалите комментарий в последней строке, вы фактически получите ошибку компилятора. [

] [
] [

]Строковые литералы не допускаются C++2003[

] [

]ISO/IEC 14882-2003 §14.1:[

] [
] [

][]14.1 Параметры шаблона [][

] [

]Параметр нетипа шаблона должен иметь один из следующих (опциональноcv-квалифицированных) типов:[

] [

]- тип интеграла или перечисления, [

] [

]- указатель на объект или указатель на функцию, [

] [

]- ссылка на объект или ссылка на функцию, [

] [

]- указатель на член. [

] [
] [

]ISO/IEC 14882-2003 §14.3.2:[

] [
] [

][]14.3.2 Аргументы шаблона, не относящиеся к типу [][

] [

] - параметр-параметр шаблона, не относящийся к типу шаблона: [

] [

]- интегральное константно-выражение интегрального или перечислительного типа; или[

] [

]- имя параметра-параметра нетипа; или [

] [

]- адрес объекта или функции с внешней связью, включая шаблоны и шаблоны функций, но исключая нестатические члены класса, выраженные как & id выражение, где & является необязательным, если имя ссылается на функцию или массив, или если соответствующий шаблонный параметр является ссылкой; или[

] [

]- указатель на член, выраженный как описано в 5.3.1.[

]. [

][Примечание: строковый литерал (2.13.4) не удовлетворяет требованиям ни одной из этих категорий и поэтому не является приемлемым шаблоном-аргументом[

]. [

] [Пример: [

] [
] [
template<class T, char* p> class X { 
  //... 
  X(); 
  X(const char* q) { /* ... */ } 
}; 

X<int,"Studebaker"> x1; //error: string literal as template-argument 
char p[] = "Vivisectionist"; 
X<int,p> x2; //OK 
] [
] [

]-окончательный пример] -окончательный комментарий]. [

] [
] [

] И похоже, что это не изменится в грядущем C++0X, [] см. текущий проект 14.4.2 Шаблонные нетипичные аргументы [].[

].
4
ответ дан 27 November 2019 в 02:07
поделиться

На основании ваших комментариев под ответом Нила, есть еще одна возможность:

#include <iostream>

static const char* eventNames[] = { "event_A", "event_B" };

enum EventId {
        event_A = 0,
        event_B
};

template <int EventId>
class Event
{
public:
   Event() {
     name_ = eventNames[EventId];
   }
   void print() {
        std::cout << name_ << std::endl;
   }
private:
   const char* name_;
};

int main()
{
        Event<event_A>().print();
        Event<event_B>().print();
}

распечатать

event_A
event_B
6
ответ дан 27 November 2019 в 02:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: