考虑以下代码:
template <typename C>
void boo (C&& c) {
c ();
}
template <typename T>
void foo (T&& v) { // (X)
boo ([&v] () { some_func (std::forward<T> (v)); }); // (Y)
}
Run Code Online (Sandbox Code Playgroud)
就我而言v,(X)是转发参考。如果v转发参考(Y)是通过引用捕获的,是否也是转发参考?还是应该以不同的方式编写它以利用转发功能?
这是代码:
#include <iostream>
#include <string>
using namespace std;
class Foo {
public:
operator string() const { return n; }
string n {"foo"};
};
int main (int argc, char** argv) {
string s {Foo{}};
cout << s << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这段代码使用gcc 4.8.3编译,但它不能使用clang 3.5进行编译,有人能告诉我它有什么问题吗?
我收到这样的错误:
main.cpp:45:12: error: no matching constructor for initialization of 'string' (aka 'basic_string<char>')
string s {Foo{}};
^ ~~~~~~~
Run Code Online (Sandbox Code Playgroud)
clang --version:
clang version 3.5.0 (tags/RELEASE_350/final 216961)
Target: x86_64-suse-linux
Thread model: posix
Run Code Online (Sandbox Code Playgroud)
谢谢
考虑:
struct Foo {
Foo () { std::cout << "default ctor" << std::endl; }
Foo (const Foo&) { std::cout << "copy ctor" << std::endl; }
Foo& operator= (const Foo&) { std::cout << "copy op" << std::endl; return *this; }
Foo (Foo&&) { std::cout << "move ctor" << std::endl; }
Foo& operator= (Foo&&) { std::cout << "move op" << std::endl; return *this; }
~Foo () { std::cout << "dtor" << std::endl; }
};
Foo process1 (Foo&& foo) {
return foo;
} …Run Code Online (Sandbox Code Playgroud) 我遇到了一些需要编写两个函数的情况,其中一个函数应该用原始类型调用std::string.另一个应该用其他类型调用.
到目前为止,我以工作解决方案结束
template <typename...>
struct Void_t_helper {
using type = void;
};
template <typename... Ts>
using Void_t = typename Void_t_helper<Ts...>::type;
template <typename T, typename = void>
struct Is_string : std::false_type {};
template <typename T>
struct Is_string<T, Void_t<decltype (std::declval<T> ().c_str ())>> : std::is_same<decltype (std::declval<T> ().c_str ()), const char*>::type {};
template <typename T>
std::enable_if_t<Is_string<T>::value || std::is_arithmetic<T>::value, void> foo (T) {
std::cout << "string or primitive\n";
}
template <typename T>
std::enable_if_t<!Is_string<T>::value && !std::is_arithmetic<T>::value, void> foo (T) {
std::cout << "other type\n"; …Run Code Online (Sandbox Code Playgroud) 所以我有一些看起来像这样的"复杂"代码:
namespace details {
template <typename T>
T do_smth_impl (T&& v) {
// process
return std::move (v);
}
}
template <typename T>
T do_smth (T v) {
return details::do_smth_impl (std::move (v));
}
Run Code Online (Sandbox Code Playgroud)
details::do_smth_impl()采用转发引用,但因为它在details命名空间中并且仅用作实现细节(在这种情况下,不需要将它放在不同的函数中,但我真的需要将它分开,因为有多个do_smth_impl()函数可以处理不同的函数类型)我真的确定只有rvalue引用将被传递给impl函数是否需要返回std::forward<T> (v)?
当我使用 CMake 时,我在将二进制数据嵌入到可执行文件中时遇到了一些问题。两个选项的代码相同,如下所示:
\n\n#include <iostream>\n\nextern char _binary_res_txt_start;\nextern char _binary_res_txt_end;\n\nint main (int, char**) {\n for (char* c = &_binary_res_txt_start; c != &_binary_res_txt_end; ++c) {\n std::cout << *c;\n } \n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n当我用 GCC 编译它时:
\n\ng++ -std=c++17 -Wall -Wextra -Wpedantic -Werror=return-type -Wl,--format=binary -Wl,res.txt -Wl,--format=default main.cpp -o main\nRun Code Online (Sandbox Code Playgroud)\n\n我的res.txt文件存储简单的“HELLO WORLD”文本,我得到适当的输出,所以一切都按预期进行。
\n\n现在我想使用 CMake 编译这段代码,所以我的尝试是:
\n\ncmake_minimum_required(VERSION 3.10)\nset(app_name main)\nproject(${app_name} CXX)\nset(BIN_DIR "${PROJECT_SOURCE_DIR}/bin")\nset(OPTIMIZATION_LEVEL " -O0")\nset(COMPILE_FLAGS_MAIN "-Wall -Wextra -Wpedantic -Wno-deprecated-declarations -Wno-unused-parameter -Wno-unused-variable -Wl,--format=binary -Wl,res.txt -Wl,--format=default")\nset(COMPILE_FLAGS_RELEASE "${COMPILE_FLAGS_MAIN} ${OPTIMIZATION_LEVEL}")\nset(CPP_STD "17")\nset(CPP_STD_REQUIRED "ON")\nset(CPP_EXTENSION_REQUIRED "OFF")\n\nfile(GLOB_RECURSE SOURCES …Run Code Online (Sandbox Code Playgroud)