在C++标准[temp.over.link]中,解释了函数模板等价性的确定不应涉及编译器的“英勇努力”。
例如,C++ 标准提出了以下建议:
// guaranteed to be the same
template <int I> void f(A<I>, A<I+10>);
template <int I> void f(A<I>, A<I+10>);
// guaranteed to be different
template <int I> void f(A<I>, A<I+10>);
template <int I> void f(A<I>, A<I+11>);
// ill-formed, no diagnostic required
template <int I> void f(A<I>, A<I+10>);
template <int I> void f(A<I>, A<I+1+2+3+4>);
Run Code Online (Sandbox Code Playgroud)
此规则是否也适用于涉及元编程的情况,如下例所示?
template<class T>
struct t_{
using type = T;
};
//ill-formed or different?
template<class T> T f(T);
template<class T> typename t_<T>::type f(T);
Run Code Online (Sandbox Code Playgroud) 在使用gcc7测试C++ 17演绎指导行为时,我发现此示例失败:
template<class T>
struct S{
S(T&& v){}
};
int i=10;
auto v = S(i);
Run Code Online (Sandbox Code Playgroud)
根据我从cpp引用中读到的内容,我认为v应该是类型S<int &>.然而gcc7没有编译这段代码抱怨a int&不能绑定到a int &&(通用引用机制失败).
所以我的问题是:
应该gcc7推断出v类型S<int&>?
工作草案标准中哪里描述了自动扣除指南?
考虑这个示例代码:
template <class T>
using pt_type = typename T::type;
template <class T>
class V {
using type = int;
public:
using pt = pt_type<V>;
};
void g() {
V<int>::pt a; // Does compile
pt_type<V<int>> b; // Does not compile
}
Run Code Online (Sandbox Code Playgroud)
V<int>::pt是别名pt_type<V<int>>.然而,它被定义的事实取决于它被引用的背景.
在C++标准中解释的是,模板参数替换模板参数是在提到别名特化的上下文中执行的?
我有一个Assert用于评估断言的函数:
如果前提条件在运行时失败,该函数将输出一条错误消息并终止程序。
如果常量表达式中的前提条件失败,则会导致编译时错误。
我希望当断言在常量计算表达式中失败时,该函数也会生成编译时错误:
const int a = (Assert(false),0); //generate a runtime error
//=> I would like it generates a compile time error
Run Code Online (Sandbox Code Playgroud)
我考虑过使用std::is_constant_evaluated:compiler-explorer
#include <type_traits>
using namespace std;
void runtime_error();
constexpr void compile_time_error(){} //should generates a compile time error
constexpr void Assert(bool value){
if (value) return;
if (is_constant_evaluated())
compile_time_error();
else
runtime_error();
}
void func(){
const int a = (Assert(false),0);
}
Run Code Online (Sandbox Code Playgroud)
我只使用 GCC,我寻找了一个会导致编译时错误的内置函数,该函数是 constexpr,但没有找到。
是否有任何技巧可以在可以常量求值的表达式中获得编译时错误?
我声明一个使用挂起函数的类。这个类是由 Hilt 库在 Android 上注入的单例依赖项:
interface Foo {
suspend fun send(v: Int)
suspend fun receive(): Int
}
class FooImpl @Inject () {
var channel: Channel<Int>(2, BufferOverflow.DROP_OLDEST)
override suspend fun send(v: Int) {
channel.send(v)
}
override suspend fun receive(): Int {
channel.receive()
}
}
//FIRST CASE:
@Module
@InstallIn(SingletonComponent::class)
abstract class FooModule {
@Binds
abstract fun bindFoo(foo: FooImpl): Foo
}
Run Code Online (Sandbox Code Playgroud)
然后,如果当我调用接收函数时,它会永远被阻止。未收到数据,示例:
@AndroidEntryPoint
class Bar: Service {
@Inject
lateinit var foo: Foo
private val scope = CoroutineScope(Job() + Dispatchers.Default)
//...
fun doSomething() { …Run Code Online (Sandbox Code Playgroud) 它可能会让一些程序员感到惊讶,并且尽管可能令人惊讶,但如果没有std::vector编译器的非标准支持,则无法实现.问题基本上在于能够在原始存储区域上执行指针运算.论文,p0593:出现在@ShafikYaghmour答案中的低级对象操纵对象的隐式创建,清楚地揭示了问题,并提出修改标准,以便更容易实现像容器和其他法律级编程技术的矢量.
然而,我想知道是否没有工作来实现一个类型,std::vector只相当于使用语言提供的内容而不使用标准库.
目标是在原始存储区域中逐个构造向量元素,并能够使用迭代器访问这些元素.这相当于std :: vector上的push_back序列.
为了解问题,请简单介绍std::vector在libc ++或libstdc ++ 中执行的操作:
void access_value(std::string x);
std::string s1, s2, s3;
//allocation
auto p=static_cast<std::string*>(::operator new(10*sizeof(std::string)));
//push_back s1
new(p) std::string(s1);
access_value(*p);//undefined behavior, p is not a pointer to object
//push_back s2
new(p+1) std::string(s2);//undefined behavior
//, pointer arithmetic but no array (neither implicit array of size 1)
access_value(*(p+1));//undefined behavior, p+1 is not a pointer to object
//push_back s2
new(p+2) std::string(s3);//undefined behavior
//, pointer arithmetic but no array …Run Code Online (Sandbox Code Playgroud)