标签: function-templates

C++ 11 条件模板函数的别名

在 C++ 11 中,我想创建一个具有两个专业化的模板别名,每个专业化解析为不同的函数。

void functionA();
void functionB();

template<typename T = char>
using Loc_snprintf = functionA;

template<>
using Loc_snprintf<wchar_t> = functionB;
Run Code Online (Sandbox Code Playgroud)

所以我可以打电话给eg Loc_snprintf<>(),它决定了functionA()

显然似乎不可能(编译)。是否有一些最终简单的东西可以模仿它(也许使用类模板)?

c++ function-templates c++11 template-aliases

5
推荐指数
1
解决办法
124
查看次数

C++ 重载函数的地址

我有以下小的 C++ 代码示例,但我无法弄清楚为什么编译器以这种方式工作,尽管我花了很多时间研究 cppreference。我将不胜感激任何解释!神箭

#include <type_traits>

template<typename Tp>
struct depend_type
{
  constexpr static bool false_ = false;
};

template<typename Tp>
struct cont
{
  using x = void;

  static_assert(std::is_same_v<Tp, int>);
  // if uncomment, will be complie error -> 'cont<Tp>::x' instantiated with 'void (*p)(int) = func;'
//   static_assert(depend_type<Tp>::false_); 
};

template<typename Tp>
void func(Tp)
{
}

template<typename Tp>
typename cont<Tp>::x func(Tp);

int main(int /* argc */, char * /*argv*/[])
{
//  func(1); is ambiguous call
  void (*p)(int) = func; // why is …
Run Code Online (Sandbox Code Playgroud)

c++ function-templates overload-resolution template-meta-programming

5
推荐指数
1
解决办法
186
查看次数

在哪里放置成员函数模板

周期性地让我感到沮丧的C++的一个方面是决定模板在头文件(传统上描述接口)和实现(.cpp)文件之间的位置.模板通常需要进入标题,暴露实现,有时会引入额外的标题,以前只需要包含在.cpp文件中.我最近又遇到了这个问题,下面显示了它的简化示例.

#include <iostream> // for ~Counter() and countAndPrint()

class Counter
{
  unsigned int count_;
public:
  Counter() : count_(0) {}
  virtual ~Counter();

  template<class T>
  void
  countAndPrint(const T&a);
};

Counter::~Counter() {
    std::cout << "total count=" << count_ << "\n";
}

template<class T>
void
Counter::countAndPrint(const T&a) {
  ++count_;
  std::cout << "counted: "<< a << "\n";
}

// Simple example class to use with Counter::countAndPrint
class IntPair {
  int a_;
  int b_;
public:
  IntPair(int a, int b) : a_(a), b_(b) {}
  friend std::ostream & …
Run Code Online (Sandbox Code Playgroud)

c++ member-functions function-templates

4
推荐指数
1
解决办法
2340
查看次数

为什么Stroustrup的书会演示默认的函数模板参数,这在当时是不允许的?

任何人都可以解释为什么在第三版C++编程语言的第13章中,Stroustrup说明了函数模板的默认参数,尽管C++(pre C++ 11)不支持它们?这是Stroustrup在第13.4.1节中给出的示例:

明确指定每个调用的比较是繁琐的.幸运的是,很容易选择默认值,因此只需要明确指定不常见的比较条件.这可以通过重载来实现:

template<class T, class C>
int compare(const String<T>& str1, const String<T>& str2); // compare using C
template<class T>
int compare(const String<T>& str1, const String<T>& str2); // compare using Cmp<T>
Run Code Online (Sandbox Code Playgroud)

或者,我们可以提供普通约定作为默认模板参数:

template <class T, class C = Cmp<T> >
int compare(const String<T>& str1, const String<T>& str2)
Run Code Online (Sandbox Code Playgroud)

这是编译器错误:

错误:默认模板参数可能不在函数模板中使用

c++ function-templates

4
推荐指数
1
解决办法
612
查看次数

实例化函数模板的编译问题

请考虑以下代码:

#include <iostream>

struct S {
  void f(const char* s) {
    std::cout << s << '\n';
  }
};

template <typename... Args, void(S::*mem_fn)(Args...)>
void invoke(S* pd, Args... args) {
  (pd->*mem_fn)(args...);
}

int main() {
  S s;
  void(*pfn)(S*, const char*) = invoke<const char*, &S::f>;
  pfn(&s, "hello");
}
Run Code Online (Sandbox Code Playgroud)

编译代码时,clang会出现以下错误:

main.cpp:16:33: error: address of overloaded function 'invoke' does not match required type 'void (S *, const char *)'
  void(*pfn)(S*, const char*) = invoke<const char*, &S::f>
                                ^~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:10:6: note: candidate template ignored: invalid explicitly-specified argument …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer function-templates variadic-templates c++11

4
推荐指数
1
解决办法
760
查看次数

定义类模板的友元函数模板

我想定义一个类模板的函数模板.代码看起来像这样.

template<int M>
struct test{
private:
    int value;

    template<int N = 2 * M>
    friend auto foo(test const t){
        test<N> r;
        r.value = t.value;
        return r;
    }
};

int main(){
    test<1> t;
    foo(t);// expected to return test<2>
    foo<1>(t);// expected to return test<1>
    foo<3>(t);// expected to return test<3>
}
Run Code Online (Sandbox Code Playgroud)

但它不会编译.与以前的问题相比,下面列出了差异.

  1. 函数模板的结果涉及类模板的另一个实例化.似乎必须在外部定义函数模板.但我不确定.
  2. 函数模板使用默认模板参数.因此,如果在类外部定义了函数模板,则需要辅助函数模板.

编译错误g++ -std=c++1z:

a.cpp: In instantiation of 'auto foo(test<M>) [with int N = 2; int M = 1]':
a.cpp:16:10:   required from here
a.cpp:4:9: error: 'int test<2>::value' is private …
Run Code Online (Sandbox Code Playgroud)

c++ templates friend-function function-templates class-template

4
推荐指数
1
解决办法
168
查看次数

可以将C ++自由函数用作别名吗?

我有一个带有一个高度模板化的免费函数的名称空间,例如:

namespace a
{
    template<typename T, typename K, typename H>
    void f(T t, K k, std::vector<H> h_vec = {})
    { /* body */ }
}
Run Code Online (Sandbox Code Playgroud)

在另一个命名空间中,为了方便起见,我想为一堆特定用法使用一些别名,例如:

namespace b
{
    using my_specific_f = a::f<int,string,char>;
}
Run Code Online (Sandbox Code Playgroud)

这将使我能够为函数提供更好的命名,因为f在我正在研究的代码库中这是非常通用的(请记住,我在这里仅提供简化的示例来说明这一点)。但是不幸的是,这显然是语言所禁止的。

因此,在第二次尝试中,我尝试使用函数指针:

namespace b
{
    auto my_specific_f = &a::f<int,string,char>
}
Run Code Online (Sandbox Code Playgroud)

这通常可以正常工作,但是在我的情况下,由于f没有一个默认参数,因此我认为它不会导致该函数具有一个以上的函数指针(在本例中为两个),并且只能使用三个参数版本。

此时,我只是放弃了,只是简单地my_specific_f将其体内的调用重定向到f

namespace b
{
    void my_specific_f(int i, string s, vector<char> v = {} )
    {
        a::f(i,s,v);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我不太喜欢这种解决方案,因为它会导致较少的可维护性,以防万一f要更改其签名,因为所有重定向功能都需要进行协调调整,而我最初的计划是创建多个别名。

我还有什么可以尝试的吗?在将来的标准发布中甚至可能还是可能?

c++ alias typedef using function-templates

4
推荐指数
1
解决办法
174
查看次数

不带参数的C ++可变函数

我有多个类(FooBar这里简单)

struct Bar {};
struct Foo {};
Run Code Online (Sandbox Code Playgroud)

和一个采用单个模板参数并根据该类型执行某些操作的函数:

template <typename T>
constexpr void doSomething() { cout << "Am I a Foo? " << is_same<T,Foo>::value << endl; }
Run Code Online (Sandbox Code Playgroud)

在我的代码中,为我提供了Foos和Bars 的模板参数包,并且应该doSomething()在它们的每个参数上调用函数(我不在乎函数的执行顺序)。

doStuff<Foo, Bar, Bar>(); // --> True / False / False
Run Code Online (Sandbox Code Playgroud)

到目前为止,我唯一能想到的解决方案是:

template <typename... Ts>
class Doer;

template <>
struct Doer <> {
    static constexpr void doStuff() {}
};

template <typename Head, typename... Tail>
struct Doer <Head, Tail...> {
    static constexpr void …
Run Code Online (Sandbox Code Playgroud)

c++ variadic-functions function-templates template-meta-programming variadic-templates

4
推荐指数
1
解决办法
124
查看次数

如何理解T&amp;和T const&amp;的偏序规则

template <typename T>
void show(T&);       // #1
template <typename T>
void show(T const&); // #2

int main()
{
    int a = 0;
    show(a);        // #1 to be called
}
Run Code Online (Sandbox Code Playgroud)

我对这些偏序规则感到困惑。以下是一些引用:[temp.deduct.partial]/5

在完成偏序之前,对用于偏序的类型执行某些转换:

  • 如果P是引用类型,P则替换为引用的类型。

  • 如果A是引用类型,A则替换为引用的类型。

[temp.deduct.partial]/6

如果PA都是引用类型(在被上面提到的类型替换之前),确定这两种类型中的哪一种(如果有的话)比另一个更符合 cv 限定;否则,出于偏序目的,这些类型被视为同样具有 cv 限定。下面将使用该确定的结果。

[temp.deduct.partial]/7

删除任何顶级 cv 限定符:

  • 如果P是 cv 限定类型,P则替换为 的 cv 非限定版本P

  • 如果A是 cv 限定类型,A则替换为 的 cv 非限定版本A。 …

c++ partial-ordering language-lawyer function-templates template-argument-deduction

4
推荐指数
1
解决办法
110
查看次数

模板参数作为函数未命名参数

这个问题继续 非静态数据成员类推导

这是未命名的参数函数,我用它来返回std::string数据类型的表示

struct Boo {};
struct Foo {};

std::string class2str(const double) { return "Floating"; };
std::string class2str(const int) { return "Fixed Point"; };
std::string class2str(const Foo) { return "Class Foo"; };
std::string class2str(const Boo) { return "Class Boo"; };

int main(int argc, char* argv[]) 
{
    int    x_a;
    double x_b;
    Foo    F;
    Boo    B;
    std::cout << "x_a     :" << class2str(x_a) << std::endl;
    std::cout << "x_b     :" << class2str(x_b) << std::endl;
    std::cout << "Foo     :" << class2str(F) << std::endl; …
Run Code Online (Sandbox Code Playgroud)

c++ templates class function-templates c++17

4
推荐指数
1
解决办法
128
查看次数