相关疑难解决方法(0)

在现代C++中是否可以将字符串文字作为参数传递给C++模板?

是否可以在"现代C++"(C++ 17或更高版本)中将字符串文字作为参数传递给C++模板?

我意识到你可以用构造函数参数做到这一点; 我只是认为将它作为模板参数更方便,而不是深埋在cpp文件中.如果这可能是现代C++的一个新功能,我很好奇.请参阅下面的伪代码我正在尝试做的事情:

伪代码示例:

// Header File /////////////////////////
template<constexpr string Name>
class ModuleBase {
public:
    ModuleBase();
    string name;
};

class xyz : ModuleBase<"xyz"> {
public:
    xyz();
};

// Cpp File //////////////////////////
template<string_literal Name>
ModuleBase<Name>::ModuleBase() {
    name = Name;
}

xyz::xyz() : ModuleBase() {

}
Run Code Online (Sandbox Code Playgroud)

c++ c++17 c++20

50
推荐指数
1
解决办法
3468
查看次数

用SFINAE检测constexpr

我正在努力升级一些C++代码以利用C++ 11中的新功能.我有一个特性类,其中有一些函数返回基本类型,这些函数大部分时间(但并不总是)返回一个常量表达式.我想根据功能是否做不同的事情constexpr.我提出了以下方法:

template<typename Trait>
struct test
{
    template<int Value = Trait::f()>
    static std::true_type do_call(int){ return std::true_type(); }

    static std::false_type do_call(...){ return std::false_type(); }

    static bool call(){ return do_call(0); }
};

struct trait
{
    static int f(){ return 15; }
};

struct ctrait
{
    static constexpr int f(){ return 20; }
};

int main()
{
   std::cout << "regular: " << test<trait>::call() << std::endl;
   std::cout << "constexpr: " << test<ctrait>::call() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

额外的int/ ...参数是这样的,如果两个函数在SFINAE之后可用,则第一个函数通过重载分辨率来选择. …

c++ templates sfinae constexpr c++11

35
推荐指数
1
解决办法
3983
查看次数

传递任何函数作为模板参数

我想将函数作为模板参数传递给函数.目前我设法做的最好的是:

template< typename F, F f >
void pass()
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

...使用的:

pass< decltype(&func), &func >();
Run Code Online (Sandbox Code Playgroud)

我真正想要的是:

pass< &func >();
Run Code Online (Sandbox Code Playgroud)

有没有办法在没有宏的情况下实现这个目标?基本上同时传递类型和值?编译器显然拥有所需的所有信息......

解决方案必须使用变量参数和返回类型.函数值在编译时使用,因此不能作为参数传递.

欢迎使用C++ 11解决方案.


编辑:用例 - 我在编译时生成绑定,我需要为每个传递的函数创建一个C++函数.这段代码的用例看起来(简化)或多或少像这样:

template < typename F, F f > 
int function_wrapper( lua_State* L ) 
{
    return dispatcher<typename return_type<F>::type>::call( L, 1, f );
}

void register_native_function( lua_Function f, const char* name )
{
    // binding call using pure C function f
}

template < typename F, F f >
void register_function( const …
Run Code Online (Sandbox Code Playgroud)

c++ templates function-pointers c++11

34
推荐指数
2
解决办法
4262
查看次数

'auto' 作为函数参数的模板参数占位符

C++20 允许使用auto函数参数类型。

它是否还允许auto用作函数参数类型的模板参数占位符(不相似,但在某种程度上符合C++17 template<auto>的精神)?

所以下面的代码,在 C++20 之前:

template<typename First, typename Second>
void printPair(const std::pair<First, Second>& p) {
    std::cout << p.first << ", " << p.second;
}
Run Code Online (Sandbox Code Playgroud)

可以写成:

void printPair(const std::pair<auto, auto>& p) {
    std::cout << p.first << ", " << p.second;
}
Run Code Online (Sandbox Code Playgroud)

确实可以编译并与概念的实验性 GCC 实现一起很好地工作

它是 C++20 的合法语法吗?


相关:C++ 概念的通配符说“接受这个模板参数的任何东西”

c++ templates auto c++20

25
推荐指数
1
解决办法
1424
查看次数

通用成员函数指针作为模板参数

考虑以下代码:

#include <iostream>
using namespace std;

class hello{
public:
    void f(){
        cout<<"f"<<endl;
    }
    virtual void ff(){
        cout<<"ff"<<endl;
    }
};

#define call_mem_fn(object, ptr)  ((object).*(ptr))

template<R (C::*ptr_to_mem)(Args...)> void proxycall(C& obj){
    cout<<"hello"<<endl;
    call_mem_fn(obj, ptr_to_mem)();
}

int main(){
    hello obj;
    proxycall<&hello::f>(obj);
}
Run Code Online (Sandbox Code Playgroud)

当然,这不会在第16行编译,因为编译器不知道是什么R,C并且Args,是.但还有另一个问题:如果有人试图在之前定义这些模板参数ptr_to_mem,他会遇到这种糟糕的情况:

template<typename R, typename C, typename... Args, R (C::*ptr_to_mem)(Args...)> 
                             //  ^variadic template, but not as last parameter!
void proxycall(C& obj){
    cout<<"hello"<<endl;
    call_mem_fn(obj, ptr_to_mem)();
}

int main(){
    hello obj;
    proxycall<void, hello, &hello::f>(obj);
}
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,g ++没有抱怨 …

c++ function-pointers variadic-templates c++11

24
推荐指数
1
解决办法
3万
查看次数

用通用函数指针参数化函数模板的简洁方法

考虑以下案例:我有

int bar1();
double bar2();
Run Code Online (Sandbox Code Playgroud)

我想要:

foo<bar1>(); // calls bar1, then uses its result.
foo<bar2>(); // calls bar2, then uses its result.
Run Code Online (Sandbox Code Playgroud)

天真的写模板方式foo()是使用附加参数:

template <typename T, T (*f)()> void foo () {
  // call f, do something with result
}
Run Code Online (Sandbox Code Playgroud)

这有效,但我需要做丑陋的语法:

foo<decltype(bar1()), bar1>(); // calls bar1, then uses its result
Run Code Online (Sandbox Code Playgroud)

我想写一些漂亮的东西,就像上面一样foo<bar1>.

PS请不要建议在运行时接受参数.我只需要使用函数指针进行编译时参数化.

PS抱歉忘记提及:我正在寻找C++ 14解决方案.C++ 17赞赏,我赞成使用C++ 17解决方案,但项目现在使用C++ 14构建,我不能在最近的将来改变它.

c++ templates decltype c++14

23
推荐指数
1
解决办法
1135
查看次数

检查类型是否是模板的实例化

我想在编译期间检查类型是否是特定模板的实例化.

例如:

  1. std::vector<int> 实例化 std::vector
  2. std::array<int, 5> 实例化 std::array

我可以进行适用于案例1的测试,但不适用于案例2.

#include <iostream>
#include <type_traits>
#include <string>
#include <vector>
#include <array>
#include <queue>
template<template<typename...> class, typename...>
struct is_instantiation : public std::false_type {};

template<template<typename...> class U, typename... T>
struct is_instantiation<U, U<T...>> : public std::true_type {};

int main() {
    using A = std::vector<int>;
    std::cout << is_instantiation<std::vector, A>::value << "\n";
    std::cout << is_instantiation<std::queue, A>::value << "\n";
    // std::cout << is_instantiation<std::array, A>::value << "\n";
}
Run Code Online (Sandbox Code Playgroud)

如何让它适用于这两种情况?

我试过汽车,但无法使它工作.

C++中模板参数中auto的优点17

c++ templates auto c++17

23
推荐指数
1
解决办法
719
查看次数

Define a function in function declaration using std::iterator traits and auto

Today I tried to implement radix sort. The function must have two variables: begin iterator and end iterator, and can have third: some function that must return the integer type to sort by. By default it must be the identity function.

My tries look like (sorry, code looks very long and dirty, but it's just a try):

template<class ForwardIt>
void radix_sort(
    ForwardIt first,
    ForwardIt last,
    std::function<auto(typename std::iterator_traits<ForwardIt>::value_type)> get_value =
    [](const typename std::iterator_traits<ForwardIt>::value_type& x){ return x; }) {
        // ...
} …
Run Code Online (Sandbox Code Playgroud)

c++ c++11

9
推荐指数
2
解决办法
178
查看次数

未知类型的模板模板参数

尝试在以下代码中提取模板参数值:

template<std::size_t SIZE>
class Foo {};

template <template<std::size_t> class T, std::size_t K>
auto extractSize(const T<K>&) {
    return K;
}

int main() {
    Foo<6> f1;
    Foo<13> f2;
    std::cout << extractSize(f1) << std::endl;
    std::cout << extractSize(f2) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

(作为问题的答案: 提取C++模板参数).

但是,有没有办法在不知道模板参数类型的情况下执行此操作.类似的东西(下面的代码不能编译......):

template <template<class SIZE_TYPE> class T, SIZE_TYPE K>
auto extractSize(const T<K>&) {
    return K;
}
Run Code Online (Sandbox Code Playgroud)

编译错误:

error: unknown type name 'SIZE_TYPE'
template <template<class SIZE_TYPE> class T, SIZE_TYPE K>
                                             ^
Run Code Online (Sandbox Code Playgroud)

c++ templates c++11 c++14

8
推荐指数
1
解决办法
592
查看次数

为什么不允许auto作为函数参数?

这个问题来看,很明显auto不能用作函数参数.我的问题是为什么允许返回类型,auto但函数参数不是?

auto function(auto data)
{
    //DOES something
}
Run Code Online (Sandbox Code Playgroud)

既然,进入c ++ 1z 会有很多好处,那么为什么不呢?auto

c++ c++17

6
推荐指数
2
解决办法
1777
查看次数

C++模板将函数转换为函数对象类型

我正在尝试使用std::unique_ptr自定义删除器来简化管理从各种 C API 返回给我的句柄的生命周期。这在理论上很好,但我正在努力寻找一种既在运行时最佳,又没有针对每种包装类型的样板文件堆的方法。

例如,考虑一些不透明类型foo,必须通过将其指针传递给来释放它destroy_foo

// approach 1: pass destroy_foo at runtime (bad for performance)
using foo_ptr = std::unique_ptr<foo, decltype(&destroy_foo)>;
foo_ptr bar{create_foo(...), destroy_foo};


// approach 2: make a deleter type (verbose - for many types)
struct foo_deleter
{
  void operator()(foo* p)
  {
    destroy_foo(p);
  }
};
using foo_ptr = std::unique_ptr<foo, foo_deleter>;
foo_ptr bar{create_foo(...)};
Run Code Online (Sandbox Code Playgroud)

第一种方法很难让编译器优化,因为我传递了一个函数指针,所以它被淘汰了。第二种方法似乎不必要地冗长。我有很多这样的类型想要管理,为每个类型手动创建一个类是很痛苦的。

如何定义一个类模板,它接受destroy_foo并给我一个相当于 的类型foo_deleter?或者有一个标准库模板可以做到这一点吗?

// best of both worlds - to_obj<Func> makes foo_deleter from destroy_foo...
using foo_ptr = std::unique_ptr<foo, …
Run Code Online (Sandbox Code Playgroud)

c++ templates template-meta-programming c++11

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

从异构列表中提取数据

我正在看这个关于auto in template参数优点的答案.

请考虑以下异构列表:

template <auto ... vs> struct HeterogenousValueList {};
using MyList1 = HeterogenousValueList<42, 'X', 13u>;
Run Code Online (Sandbox Code Playgroud)

现在我已经声明了一个名为的类型MyList1.如何从此类型中提取存储的数据(即42,'x'或13u)?

c++ templates variadic-templates c++17

2
推荐指数
1
解决办法
137
查看次数

推断可变参数模板参数包元素的类型

我有以下功能:

template <typename T, T... Ts> T random_value(default_random_engine &rnd)
{
    static constexpr T values [] { Ts... };
    static uniform_int_distribution<size_t> distribution(0, sizeof...(Ts) - 1);
    return values[distribution(rnd)];
}
Run Code Online (Sandbox Code Playgroud)

这就是这样称呼的:

MyEnum val = random_value<MyEnum, MyEnum::val1, MyEnum::val2, MyEnum::val3>(rnd);
Run Code Online (Sandbox Code Playgroud)

是否有可能以这种方式重新定义它,我不需要明确指定T?因此它被称为:

MyEnum val = random_value<MyEnum::val1, MyEnum::val2, MyEnum::val3>(rnd);
Run Code Online (Sandbox Code Playgroud)

c++ templates variadic-templates c++11

0
推荐指数
1
解决办法
89
查看次数